A Za, A Za, Fighting...

坚信:勤能补拙

问题描述及代码:

  1 /*
  2  * Problem:
  3  * given you the coins, and the total amount of money to change, find a solution
  4  * for this change which minimize the number of coins needed.
  5  *
  6  * Example:
  7  * coins[] = {1, 5, 10, 21, 25};
  8  * money = 19;
  9  * solution[] = {10, 5, 1, 1, 1, 1};
 10  *
 11  * Points:
 12  * Dynamic Programming
 13  * Greey Algorithm here is usually uncorrect
 14  */
 15 #include<stdio.h>
 16 #include<stdlib.h>
 17 #include<string.h>
 18 #define MAX_COINS 10
 19 #define MAX_MONEY 32767
 20 #define INF 0x7FFFFFFF
 21 int coins_num, coins[MAX_COINS];
 22 int total, changes_num[MAX_MONEY], changes[MAX_MONEY];
 23 
 24 int
 25 is_continue()
 26 {
 27     char ch[2];
 28     while(1) {
 29         printf("Are you gonna continue this game(Y if yes, or N)?\n");
 30         scanf("%s", ch);
 31         if(ch[0== 'Y' || ch[0== 'y')
 32             return 1;
 33         else if(ch[0== 'N' || ch[0== 'n')
 34             return 0;
 35     }
 36 }
 37 
 38 void
 39 input()
 40 {
 41     int i;
 42     printf("Enter the number of coins: ");
 43     scanf("%d"&coins_num);
 44     printf("Enter the amount of coins(ascending order, separated by space): \n");
 45     for(i=0; i<coins_num; i++)
 46         scanf("%d", coins+i);
 47     printf("Enter the amount of money to change: ");
 48     scanf("%d"&total);
 49 }
 50 
 51 void
 52 output()
 53 {
 54     int i, tmp;
 55     printf("Solution: \n");
 56     printf("Minimum number of coins needed: %d\n", changes_num[total]);
 57     printf("Coins: \n");
 58     tmp = total;
 59     while(tmp > 0) {
 60         printf("%d ", changes[tmp]);
 61         tmp -= changes[tmp];
 62     }
 63     printf("\n");
 64 }
 65 
 66 /*
 67  * Dynamic Programming: f(m) = min (f[m-coins[i] + 1)
 68  * O(N*K), N is the number of coins, K is the total amount of money to change
 69  */
 70 void 
 71 solve()
 72 {
 73     int i, j, k, min;
 74     changes_num[0= 0;
 75     for(i=1; i<=total; i++) { /* Money: from '1' to 'total' */
 76         min = INF;
 77         k = -1;
 78         for(j=0; j<coins_num; j++) { /* Coins: ascending, and always contains '1' */
 79             if(i >= coins[j]) {
 80                 if(min > changes_num[i-coins[j]]+1) {
 81                     min = changes_num[i-coins[j]]+1;
 82                     k = j;
 83                 }
 84             } else
 85                 continue;
 86         }
 87         changes_num[i] = min;
 88         changes[i] = coins[k];
 89     }
 90 }
 91 
 92 int
 93 main(int argc, char **argv)
 94 {
 95     while(is_continue()) {
 96         input();
 97         solve();
 98         output();
 99     }
100 }
posted @ 2010-09-29 14:18 simplyzhao 阅读(747) | 评论 (0)编辑 收藏
问题:
http://ace.delos.com/usacoprob2?a=KIjVa3gj0ap&S=barn1

思路:
简单的贪心算法
一直不敢怎么用贪心算法(这题比较好理解),因为不知道该如何证明其正确性
如何保证每次选择当前最优解最后可以得到整体的最优解?

对于该题:
假设存在M块boards,那么从最左端到最右端(指存在cow的stall)可以存在M-1处gap
最优子结构:
设f(x)表示存在x块boards时的the minimum number of stalls that must be blocked,那么
             f(x) = min(f(x-1) + gap[i] that hasn't been selected)
贪心选择性质: 每次从尚未选择过的gaps中选择最大的gap即可得到最优解(假设为gap[x1], gap[x2], ...gap[x(M-1)])
证明(反证):
假设存在一个最优解,其不包含gap[x(i)]
那么,采用cut-and-paste方法即可证明其不是最优解

代码:
 1 /*
 2 ID: simplyz2
 3 LANG: C
 4 TASK: barn1
 5 */
 6 #include<stdio.h>
 7 #include<stdlib.h>
 8 #include<string.h>
 9 #define MAX_LEN 205
10 #define Min(a,b) ((a)<(b) ? (a) : (b))
11 int M, S, C;
12 int rt, stalls[MAX_LEN], diff[MAX_LEN];
13 
14 int
15 asc_cmp(const void *arg1, const void *arg2)
16 {
17     return (*(int *)arg1) - (*(int *)arg2);
18 }
19 
20 int
21 desc_cmp(const void *arg1, const void *arg2)
22 {
23     return (*(int *)arg2) - (*(int *)arg1);
24 }
25 
26 void
27 init()
28 {
29     int i;
30     for(i=0; i<C; i++
31         scanf("%d", stalls+i);
32     qsort(stalls, C, sizeof(int), asc_cmp);
33     rt = stalls[C-1- stalls[0+ 1;
34     for(i=1; i<C; i++)
35         diff[i-1= stalls[i] - stalls[i-1- 1;
36     qsort(diff, C-1sizeof(int), desc_cmp);
37 }
38 
39 void
40 solve()
41 {
42     int i, up;
43     up = Min(C-1, M-1);
44     for(i=0; i<up; i++)
45         rt -= diff[i];
46     printf("%d\n", rt);
47 }
48 
49 int
50 main(int argc, char **argv)
51 {
52     freopen("barn1.in""r", stdin);
53     freopen("barn1.out""w", stdout);
54     while(scanf("%d %d %d"&M, &S, &C) != EOF) {
55         init();
56         solve();
57     }
58     return 0;
59 }
posted @ 2010-09-29 10:49 simplyzhao 阅读(229) | 评论 (0)编辑 收藏
问题:
http://ace.delos.com/usacoprob2?a=sAaEFWx5xo1&S=milk2

思路:
如果想通了,该题还是挺简单的
首先按照开始时间进行排序,然后依次查看相邻时间段是否可以合并
针对合并后的时间段,很容易即可求出解

代码:
 1 /*
 2 ID: simplyz2
 3 LANG: C
 4 TASK: milk2
 5 */
 6 #include<stdio.h>
 7 #include<stdlib.h>
 8 #include<string.h>
 9 #define MAX_LEN 5001
10 #define Max(a,b) ((a)>(b) ? (a) : (b))
11 struct Intv {
12     int begin, end;
13 } intvs[MAX_LEN], merge[MAX_LEN];
14 int num, m_num;
15 
16 int
17 compare(const void *arg1, const void *arg2)
18 {
19     return (((struct Intv *)arg1)->begin - ((struct Intv *)arg2)->begin);
20 }
21 
22 void
23 merge_intv()
24 {
25     int i; 
26     m_num = 0;
27     qsort(intvs, num, sizeof(struct Intv), compare);
28     merge[m_num] = intvs[0];
29     for(i=1; i<num; i++) {
30         if(intvs[i].begin > merge[m_num].end) 
31             merge[++m_num] = intvs[i];
32         else if(intvs[i].end > merge[m_num].end) 
33             merge[m_num].end = intvs[i].end;
34     }
35 }
36 
37 void
38 solve()
39 {
40     int i, rt_a, rt_b;
41     rt_a = rt_b = 0;
42     for(i=0; i<=m_num; i++) {
43         rt_a = Max(rt_a, merge[i].end - merge[i].begin);
44         if(i)
45             rt_b = Max(rt_b, merge[i].begin - merge[i-1].end);
46     }
47     printf("%d %d\n", rt_a, rt_b);
48 }
49 
50 int
51 main(int argc, char **argv)
52 {
53     int i;
54     freopen("milk2.in""r", stdin);
55     freopen("milk2.out""w", stdout);
56     while(scanf("%d"&num) != EOF) {
57         for(i=0; i<num; i++)
58             scanf("%d %d"&intvs[i].begin, &intvs[i].end);
59         merge_intv();
60         solve();
61     }
62     return 0;
63 }
posted @ 2010-09-27 15:01 simplyzhao 阅读(241) | 评论 (0)编辑 收藏
问题:
http://ace.delos.com/usacoprob2?a=sAaEFWx5xo1&S=beads

思路:
如果纯粹枚举的话,代码还是挺简单的(关键是将循环结构巧妙地用线性结构表示: s -> ss)
枚举的复杂度很容易地看出是O(n*n),对于本题,还是没问题的

官方给出的Analysis中,提供了一种O(n)的动态规划的解法,却始终想不明白,艾...
有时间再继续思考
posted @ 2010-09-27 14:58 simplyzhao 阅读(212) | 评论 (0)编辑 收藏
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1273

思路:
第一道最大流,Edmonds-Karp算法
参考了别人的代码,其实自己也能写出来,不过肯定没有这么精致(*^__^*) 嘻嘻……
从别人的代码里学到很多,例如:
一条路径只需要pre[]数组进行保存即可,路径的残留容量也可以边扩展(BFS)边记录,还有代码居然就只需要一个残留网络的二维数组

代码:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define MAX_M 201
 5 #define INF 0x7FFFFFFF
 6 #define Min(a,b) ((a)<(b) ? (a) : (b))
 7 int n, m, source, sink;
 8 int pre[MAX_M]; /* excellent for path recording */
 9 int flow[MAX_M];
10 int residual[MAX_M][MAX_M]; /* only need this matrix */
11 int queue[MAX_M];
12 
13 int
14 bfs() /* operation on the residual network */
15 {
16     int i, head, tail, cur;
17     head = -1;
18     tail = 0;
19     memset(pre, -1sizeof(pre));
20     for(i=1; i<=m; i++)
21         flow[i] = INF;
22     queue[tail] = source;
23     pre[source] = 0;
24     while(head < tail) {
25         ++head;
26         cur = queue[head];
27         if(cur == sink)
28             return flow[sink];
29         for(i=1; i<=m; i++) {
30             if(pre[i]!=-1 || !residual[cur][i])
31                 continue;
32             pre[i] = cur;
33             flow[i] = Min(flow[cur], residual[cur][i]);
34             ++tail;
35             queue[tail] = i;
36         }
37     }
38     return -1;
39 }
40 
41 int
42 edmonds_karp()
43 {
44     int tmp, next, cur, rt = 0;
45     while(1) {
46         tmp = bfs();
47         if(tmp == -1/* there's no argment path */
48             return rt;
49         rt += tmp;
50         cur = sink;
51         while(cur != source) {
52             next = cur;
53             cur = pre[cur];
54             residual[cur][next] -= tmp;
55             residual[next][cur] += tmp;
56         }
57     }
58 }
59 
60 int
61 main(int argc, char **argv)
62 {
63     int i, f, t, c, ans;
64     while(scanf("%d %d"&n, &m) != EOF) {
65         memset(residual, 0sizeof(residual));
66         for(i=1; i<=n; i++) {
67             scanf("%d %d %d"&f, &t, &c);
68             residual[f][t] += c; /* Attention: multiple lines */
69         }
70         source = 1;
71         sink = m;
72         ans = edmonds_karp();
73         printf("%d\n", ans);
74     }
75 }

posted @ 2010-09-16 21:10 simplyzhao 阅读(175) | 评论 (0)编辑 收藏
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2777

思路:
线段树的典型题

参考:
http://blog.csdn.net/xiaofengsheng/archive/2009/03/03/3953265.aspx

代码:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #define MAX_N 100001
  5 #define MAX_T 31
  6 #define LEFT(i) (i<<1)
  7 #define RIGHT(i) ((i<<1)+1)
  8 int L, T, O;
  9 struct Node {
 10     int left, right;
 11     int color;
 12 };
 13 struct Node nodes[MAX_N*3];
 14 int rt, visited[MAX_T];
 15 
 16 void
 17 build(int begin, int end, int step)
 18 {
 19     int mid;
 20     nodes[step].left = begin;
 21     nodes[step].right = end;
 22     nodes[step].color = 1;
 23     if(begin == end)
 24         return;
 25     mid = (begin+end)>>1;
 26     build(begin, mid, LEFT(step));
 27     build(mid+1, end, RIGHT(step));
 28 }
 29 
 30 void
 31 insert(int begin, int end, int color, int step)
 32 {
 33     int mid;
 34     if(nodes[step].left==begin && nodes[step].right==end) {
 35         nodes[step].color = color;
 36         return;
 37     };
 38     if(nodes[step].color != -1) {
 39         nodes[LEFT(step)].color = nodes[RIGHT(step)].color = nodes[step].color;
 40         nodes[step].color = -1/* mixed color */
 41     }
 42     mid = (nodes[step].left+nodes[step].right)>>1;
 43     if(begin > mid) 
 44         insert(begin, end, color, RIGHT(step));
 45     else if(end<=mid)
 46         insert(begin, end, color, LEFT(step));
 47     else {
 48         insert(begin, mid, color, LEFT(step));
 49         insert(mid+1, end, color, RIGHT(step));
 50     }
 51 }
 52 
 53 void
 54 calculate(int begin, int end, int step)
 55 {
 56     if(nodes[step].color != -1) {
 57         if(!visited[nodes[step].color]) {
 58             visited[nodes[step].color] = 1;
 59             ++rt;
 60         }
 61         return;
 62     }
 63     int mid = (nodes[step].left+nodes[step].right)>>1;
 64     if(mid < begin)
 65         calculate(begin, end, RIGHT(step));
 66     else if(mid >= end)
 67         calculate(begin, end, LEFT(step));
 68     else {
 69         calculate(begin, mid, LEFT(step));
 70         calculate(mid+1, end, RIGHT(step));
 71     }
 72 }
 73 
 74 int
 75 main(int argc, char **argv)
 76 {
 77     int i, a, b, c;
 78     char ops[2];
 79     while(scanf("%d %d %d"&L, &T, &O) != EOF) {
 80         build(1, L, 1);
 81         for(i=1; i<=O; i++) {
 82             scanf("%s", ops);
 83             if(ops[0== 'C') {
 84                 scanf("%d %d %d"&a, &b, &c);
 85                 if(a <= b)
 86                     insert(a, b, c, 1);
 87                 else
 88                     insert(b, a, c, 1);
 89             } else if(ops[0== 'P') {
 90                 scanf("%d %d"&a, &b);
 91                 rt = 0;
 92                 memset(visited, 0sizeof(visited));
 93                 if(a <= b)
 94                     calculate(a, b, 1);
 95                 else
 96                     calculate(b, a, 1);
 97                 printf("%d\n", rt);
 98             }
 99         }
100     }
101 }
posted @ 2010-09-16 10:57 simplyzhao 阅读(233) | 评论 (0)编辑 收藏
     摘要: 从简单说起,线段树其实可以理解成一种特殊的二叉树。但是这种二叉树较为平衡,和静态二叉树一样,都是提前已经建立好的树形结构。针对性强,所以效率要高。这里又想到了一句题外话:动态和静态的差别。动态结构较为灵活,但是速度较慢;静态结构节省内存,速度较快。接着回到线段树上来,线段树是建立在线段的基础上,每个结点都代表了一条线段[a , b]。长度为1的线段成为元线段。非元线段都有两个子结点,左结点代表的线...  阅读全文
posted @ 2010-09-15 18:49 simplyzhao 阅读(187) | 评论 (0)编辑 收藏

好久没写过算法了,添一个吧,写一个线段树的入门知识,比较大众化。

上次在湖大,其中的一道题数据很强,我试了好多种优化都TLE,相信只能用线段树才能过。回来之后暗暗又学了一次线段树,想想好像是第三次学了,像网络流一样每学一次都有新的体会。

把问题简化一下:

在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现过;

最基本的解法当然就是读一个点,就把所有线段比一下,看看在不在线段中;

每次询问都要把n条线段查一次,那么m次询问,就要运算m*n次,复杂度就是O(m*n)

这道题m和n都是30000,那么计算量达到了10^9;而计算机1秒的计算量大约是10^8的数量级,所以这种方法无论怎么优化都是超时

-----

因为n条线段是固定的,所以某种程度上说每次都把n条线段查一遍有大量的重复和浪费;

线段树就是可以解决这类问题的数据结构

举例说明:已知线段[2,5] [4,6] [0,7];求点2,4,7分别出现了多少次

在[0,7]区间上建立一棵满二叉树:(为了和已知线段区别,用【】表示线段树中的线段)

                                               【0,7】
                               /                                            \
                     【0,3】                                           【4,7】
                  /               \                                    /                \
       【0,1】             【2,3】                     【4,5】               【6,7】
         /      \                 /      \                     /      \                   /      \
【0,0】 【1,1】    【2,2】 【3,3】   【4,4】  【5,5】       【6,6】 【7,7】

每个节点用结构体:

struct line
{
      int left,right;//左端点、右端点
      int n;//记录这条线段出现了多少次,默认为0
}a[16];

和堆类似,满二叉树的性质决定a[i]的左儿子是a[2*i]、右儿子是a[2*i+1];

然后对于已知的线段依次进行插入操作:

从树根开始调用递归函数insert

void insert(int s,int t,int step)//要插入的线段的左端点和右端点、以及当前线段树中的某条线段
{
      if (s==a[step].left && t==a[step].right)
      {
            a[step].n++;//插入的线段匹配则此条线段的记录+1
            return;//插入结束返回
      }
      if (a[step].left==a[step].right)   return;//当前线段树的线段没有儿子,插入结束返回
      int mid=(a[step].left+a[step].right)/2;
      if (mid>=t)    insert(s,t,step*2);//如果中点在t的右边,则应该插入到左儿子
      else if (mid<s)    insert(s,t,step*2+1);//如果中点在s的左边,则应该插入到右儿子
      else//否则,中点一定在s和t之间,把待插线段分成两半分别插到左右儿子里面
      {
            insert(s,mid,step*2);
            insert(mid+1,t,step*2+1);
      }
}

三条已知线段插入过程:

[2,5]

--[2,5]与【0,7】比较,分成两部分:[2,3]插到左儿子【0,3】,[4,5]插到右儿子【4,7】

--[2,3]与【0,3】比较,插到右儿子【2,3】;[4,5]和【4,7】比较,插到左儿子【4,5】

--[2,3]与【2,3】匹配,【2,3】记录+1;[4,5]与【4,5】匹配,【4,5】记录+1

[4,6]

--[4,6]与【0,7】比较,插到右儿子【4,7】

--[4,6]与【4,7】比较,分成两部分,[4,5]插到左儿子【4,5】;[6,6]插到右儿子【6,7】

--[4,5]与【4,5】匹配,【4,5】记录+1;[6,6]与【6,7】比较,插到左儿子【6,6】

--[6,6]与【6,6】匹配,【6,6】记录+1

[0,7]

--[0,7]与【0,7】匹配,【0,7】记录+1

插入过程结束,线段树上的记录如下(红色数字为每条线段的记录n):

                                                 【0,7】
                                                      1
                               /                                              \
                     【0,3】                                             【4,7】
                         0                                                     0
                 /                 \                                     /                 \
       【0,1】                 【2,3】                【4,5】                  【6,7】
            0                           1                          2                         0
          /    \                      /      \                     /     \                    /      \
【0,0】 【1,1】       【2,2】   【3,3】       【4,4】 【5,5】     【6,6】  【7,7】
     0            0            0            0            0            0           1           0

询问操作和插入操作类似,也是递归过程,略

2——依次把【0,7】 【0,3】 【2,3】 【2,2】的记录n加起来,结果为2

4——依次把【0,7】 【4,7】 【4,5】 【4,4】的记录n加起来,结果为3

7——依次把【0,7】 【4,7】 【6,7】 【7,7】的记录n加起来,结果为1

不管是插入操作还是查询操作,每次操作的执行次数仅为树的深度——logN

建树有n次插入操作,n*logN,一次查询要logN,m次就是m*logN;总共复杂度O(n+m)*logN,这道题N不超过30000,logN约等于14,所以计算量在10^5~10^6之间,比普通方法快了1000倍;

这道题是线段树最基本的操作,只用到了插入和查找;删除操作和插入类似,扩展功能的还有测度、连续段数等等,在N数据范围很大的时候,依然可以用离散化的方法建树。

湖大的那道题目绕了个小弯子,alpc12有详细的题目和解题报告,有兴趣的话可以看看http://www.cppblog.com/sicheng/archive/2008/01/09/40791.html

线段树的经典题目就是poj1177的picturehttp://acm.pku.edu.cn/JudgeOnline/problem?id=1177

posted @ 2010-09-15 18:46 simplyzhao 阅读(221) | 评论 (0)编辑 收藏
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1456

思路:
这题就是个悲剧...
都说这题是贪心,还有并查集的优化,不过我对于贪心一直不敢用,因为不知道为什么可以贪心
然后,那就动态规划吧,结果,彻底受打击了,对于动态规划还是没掌握啊...

其实,用value[i][j]来表示前i件product到时刻j为止所得到的最大profit
          value[i][j] = max (value[i-1][j], value[i-1][j-1]+profit[i])
跟01背包的形式是一样的,所以就可以用滚动数组进行空间优化

代码:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define MAX_N 10001
 5 #define Max(a,b) ((a)<(b)?(b):(a))
 6 struct Prod {
 7     int profit;
 8     int deadline;
 9 } prods[MAX_N];
10 int n, upper, value[MAX_N];
11 
12 int
13 compare(const void *arg1, const void *arg2) /* ascend order: deadline */
14 {
15     struct Prod *= (struct Prod *)arg1;
16     struct Prod *= (struct Prod *)arg2;
17     return a->deadline-b->deadline;
18 }
19 
20 void
21 init()
22 {
23     int i;
24     for(i=0; i<n; i++)
25         scanf("%d %d"&prods[i].profit, &prods[i].deadline);
26     qsort(prods, n, sizeof(struct Prod), compare);
27     upper = prods[n-1].deadline;
28 }
29 
30 void
31 solve()
32 {
33     int i, j;
34     memset(value, 0sizeof(value));
35     for(i=0; i<n; i++) {
36         for(j=prods[i].deadline; j>=1; j--
37             value[j] = Max(value[j], value[j-1]+prods[i].profit);
38         for(j=prods[i].deadline+1; j<=upper; j++)
39             value[j] = Max(value[prods[i].deadline], value[j]);
40     }
41     printf("%d\n", value[upper]);
42 }
43 
44 int
45 main(int argc, char **argv)
46 {
47     while(scanf("%d"&n) != EOF) {
48         init();
49         solve();
50     }
51 }
posted @ 2010-09-15 16:25 simplyzhao 阅读(188) | 评论 (0)编辑 收藏
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1270

思路:
拓扑排序适合于描述事件发生的先后次序
这题,对于a>b这样的题目要求,就非常适合用拓扑排序来进行

一次AC,写的过程还接了个女朋友的电话,跟同学聊了会天,o(∩_∩)o...哈哈

代码:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define STR_LEN 207
 5 #define MAX_N 26
 6 int adj[MAX_N][MAX_N], in_dgr[MAX_N];
 7 int visited[MAX_N];
 8 int total, ch[MAX_N];
 9 char ans[MAX_N];
10 
11 int
12 init()
13 {
14     int i, f, t, len;
15     char str[STR_LEN];
16     total = 0;
17     memset(ch, 0sizeof(ch));
18     memset(in_dgr, 0sizeof(in_dgr));
19     memset(adj, 0sizeof(adj));
20     memset(visited, 0sizeof(visited));
21     memset(ans, 0sizeof(ans));
22     if(fgets(str, STR_LEN, stdin) == NULL)
23         return 0;
24     len = strlen(str);
25     for(i=0; i<len; i+=2) {
26         if(str[i]>='a' && str[i]<='z') {
27             ++total;
28             ++ch[str[i]-'a'];
29         }
30     }
31     fgets(str, STR_LEN, stdin);
32     len = strlen(str);
33     for(i=0; i<len; i+=2) {
34         if((i>>1)%2 == 0)
35             f = str[i]-'a';
36         else {
37             t = str[i]-'a';
38             adj[f][t] = 1;
39             ++in_dgr[t];
40         }
41     }
42     return 1;
43 }
44 
45 void
46 topo_sort(int depth)
47 {
48     int i, j;
49     if(depth == total) {
50         printf("%s\n", ans);
51         return;
52     }
53     for(i=0; i<MAX_N; i++) {
54         if(ch[i] && !visited[i] && !in_dgr[i]) {
55             visited[i] = 1;
56             ans[depth] = 'a'+i;
57             for(j=0; j<MAX_N; j++)
58                 if(adj[i][j])
59                     --in_dgr[j];
60             topo_sort(depth+1);
61             visited[i] = 0;
62             for(j=0; j<MAX_N; j++)
63                 if(adj[i][j])
64                     ++in_dgr[j];
65         }
66     }
67 }
68 
69 int
70 main(int argc, char **argv)
71 {
72     while(init()) {
73         topo_sort(0);
74         printf("\n");
75     }
76 }
posted @ 2010-09-14 20:00 simplyzhao 阅读(164) | 评论 (0)编辑 收藏
仅列出标题
共21页: First 7 8 9 10 11 12 13 14 15 Last 

导航

<2024年8月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜