青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

A Za, A Za, Fighting...

堅(jiān)信:勤能補(bǔ)拙

問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=3259

思路:
這題的描述挺有意思,通過(guò)某些路徑可以回到過(guò)去之類,其實(shí)就是求是否存在負(fù)權(quán)回路的問(wèn)題
Bellman-Ford算法的典型應(yīng)用
一個(gè)問(wèn)題是,Bellman-Ford用于判斷從某個(gè)源點(diǎn)可達(dá)的負(fù)權(quán)回路,而這里求的是整個(gè)圖,而且也沒(méi)有說(shuō)明該圖一定是connected的
解決上述問(wèn)題的一個(gè)方法就是添加一個(gè)頂點(diǎn),然后從該新頂點(diǎn)到每個(gè)其他頂點(diǎn)添加一條權(quán)值為0的邊

代碼:
 1 /* Bellman-Ford algorithm */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_N 501
 6 #define MAX_M 2501
 7 #define MAX_W 201
 8 #define INF 0x7FFFFFFF
 9 struct Edge {
10     int from, to;
11     int cost;
12 } edges[MAX_M*2+MAX_W+MAX_N];
13 int d[MAX_N];
14 int n, total;
15 
16 void
17 init()
18 {
19     int i, m, w, f, t, c;
20     scanf("%d %d %d"&n, &m, &w);
21     total = 0/* the number of edges */
22     for(i=0; i<m; i++) {
23         scanf("%d %d %d"&f, &t, &c);
24         edges[total].from = f;
25         edges[total].to = t;
26         edges[total++].cost = c;
27         edges[total].from = t;
28         edges[total].to = f;
29         edges[total++].cost = c;
30     }
31     for(i=0; i<w; i++) {
32         scanf("%d %d %d"&f, &t, &c);
33         edges[total].from = f;
34         edges[total].to = t;
35         edges[total++].cost = c*(-1);
36     }
37     /* in order to keep connectivity, add one vertex: '0' */
38     for(i=1; i<=n; i++) {
39         edges[total].from = 0;
40         edges[total].to = i;
41         edges[total++].cost = 0;
42     }
43 }
44 
45 void
46 relax(struct Edge *e)
47 {
48     if(d[e->from] == INF)
49         return;
50     if(d[e->to] > d[e->from]+e->cost)
51         d[e->to] = d[e->from]+e->cost;
52 }
53 
54 int
55 bellman_ford()
56 {
57     int i, j;
58     for(i=0; i<=n; i++)
59         d[i] = INF;
60     d[0= 0;
61     for(i=0; i<n; i++)  /* n+1 vertices */
62         for(j=0; j<total; j++)  /* 2*m+w+n edges */
63             relax(edges+j);
64     for(j=0; j<total; j++) {
65         if(d[edges[j].to] > d[edges[j].from]+edges[j].cost)
66             return 0;
67     }
68     return 1;
69 }
70 
71 int
72 main(int argc, char **argv)
73 {
74     int F;
75     scanf("%d"&F);
76     while(F--) {
77         init();
78         printf("%s\n", bellman_ford()==1?"NO":"YES");
79     }
80 }
posted @ 2010-09-07 22:29 simplyzhao 閱讀(314) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2394

思路:
題目說(shuō)的有點(diǎn)復(fù)雜,其實(shí)就是求單源最短路徑,Dijkstra算法
需要注意的是輸入可能有重邊
具體關(guān)于Dijkstra算法,參考算法導(dǎo)論,有詳細(xì)的證明
第一次寫(xiě)該算法,一次AC   o(∩_∩)o...哈哈

代碼:
 1 /* dijkstra algorithm */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_F 501
 6 #define MAX_C 101
 7 #define INF 0x7FFFFFFF
 8 int adj[MAX_F][MAX_F];
 9 int pos[MAX_C];
10 int in[MAX_F], d[MAX_F];
11 int f, p, c, m;
12 
13 void
14 init()
15 {
16     int i, from, to, cost;
17     memset(adj, 0sizeof(adj));
18     scanf("%d %d %d %d"&f, &p, &c, &m);
19     for(i=0; i<p; i++) {
20         scanf("%d %d %d"&from, &to, &cost);
21         if(adj[from][to]==0 || adj[from][to]>cost)
22             adj[from][to] = adj[to][from] = cost;
23     }
24     for(i=1; i<=c; i++)
25         scanf("%d", pos+i);
26 }
27 
28 void
29 dijkstra()
30 {
31     int i, j, k, cur;
32     memset(in0sizeof(in));
33     for(i=1; i<=f; i++)
34         d[i] = INF;
35     d[1= 0;
36     in[1= 1;
37     for(j=1; j<=f; j++)
38         if(!in[j] && adj[1][j])
39             d[j] = adj[1][j];
40     for(i=2; i<=f; i++) {
41         cur = INF;
42         for(j=1; j<=f; j++)
43             if(!in[j] && d[j]<=cur) {
44                 k = j;
45                 cur = d[j];
46             }
47         in[k] = 1;
48         for(j=1; j<=f; j++)
49             if(!in[j] && adj[k][j] && d[k]!=INF)
50                 if(d[j] > d[k]+adj[k][j])
51                     d[j] = d[k]+adj[k][j];
52     }
53 }
54 
55 void
56 output()
57 {
58     int i, n = 0;
59     for(i=1; i<=c; i++)
60         if(d[pos[i]] <= m) {
61             ++n;
62             pos[i] = -1;
63         }
64     printf("%d\n", n);
65     for(i=1; i<=c; i++)
66         if(pos[i] == -1)
67             printf("%d\n", i);
68 }
69 
70 int
71 main(int argc, char **argv)
72 {
73     init();
74     dijkstra();
75     output();
76 }

posted @ 2010-09-07 20:18 simplyzhao 閱讀(204) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1054

思路:
好題,枚舉 + 二分
枚舉所有可能路徑的前兩個(gè)點(diǎn)
要注意的是: starting outside the paddy on one side and ending outside the paddy on the other side

代碼:
 1 /* enumerate the first two points for each possible path */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_NUM 5001
 6 #define is_valid(x, y) ((x)>0 && (x)<=R && (y)>0 && (y)<=C)
 7 int R, C;
 8 int total;
 9 struct Point {
10     int x, y;
11 } points[MAX_NUM];
12 
13 /* from top to down, and left to right */
14 int
15 compare(const void *arg1, const void *arg2)
16 {
17     struct Point *= (struct Point *)arg1;
18     struct Point *= (struct Point *)arg2;
19     if(a->== b->x)
20         return a->- b->y;
21     return a->- b->x;
22 }
23 
24 void
25 init()
26 {
27     int i;
28     scanf("%d"&total);
29     for(i=0; i<total; i++)
30         scanf("%d %d"&points[i].x, &points[i].y);
31     qsort(points, total, sizeof(struct Point), compare);
32 }
33 
34 void
35 solve()
36 {
37     int i, j, tmp, max = 0;
38     int diff_x, diff_y;
39     struct Point p1, p2, next;
40     struct Point *ptr;
41     for(i=0; i<total; i++) {
42         for(j=i+1; j<total; j++) {
43             tmp = 2;
44             p1 = points[i];
45             p2 = points[j];
46             diff_x = p2.x - p1.x;
47             diff_y = p2.y - p1.y;
48             if(is_valid(p1.x-diff_x, p1.y-diff_y)) /* starting outside */
49                 continue;
50             if(!is_valid(p1.x+max*diff_x, p1.y+max*diff_y)) /* pruning */
51                 continue;
52             next.x = p2.x + diff_x;
53             next.y = p2.y + diff_y;
54             while(is_valid(next.x, next.y)) {
55                 if((ptr=(struct Point *)bsearch(&next, points, total, sizeof(struct Point), compare)) == NULL) {
56                     tmp = 0/* ending outside */
57                     break;
58                 }
59                 ++tmp;
60                 next.x += diff_x;
61                 next.y += diff_y;
62             }
63             max = tmp>max ? tmp : max;
64         }
65     }
66     printf("%d\n", max>2 ? max : 0);
67 }
68 
69 int
70 main(int argc, char **argv)
71 {
72     while(scanf("%d %d"&R, &C) != EOF) {
73         init();
74         solve();
75     }
76 }

posted @ 2010-09-07 17:18 simplyzhao 閱讀(227) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2421

思路:
非常類似于PKU 2485   Highways
區(qū)別在于: "there are already some roads between some villages"
如何在求最小生成樹(shù)的算法中體現(xiàn)某些路徑已經(jīng)存在了呢?
對(duì)于Prim算法,只要將已經(jīng)存在的路徑(u, v)的權(quán)重設(shè)置為0即可(為什么?)
對(duì)于Kruskal算法,比較容易理解,只要將已經(jīng)存在的路徑(u, v)進(jìn)行Union操作即可,即將u, v看作是一個(gè)連通域
posted @ 2010-09-05 19:58 simplyzhao 閱讀(224) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1861
http://acm.pku.edu.cn/JudgeOnline/problem?id=2485

思路:
這里題目并沒(méi)有明確要求求最小生成樹(shù),而是要求一顆最長(zhǎng)邊最小的生成樹(shù)
我們可以證明:
       如果T是一顆最小生成樹(shù),那么T所包含的最長(zhǎng)邊一定是所有生成樹(shù)中最小的,即最小生成樹(shù)滿足題目要求
Prove:
如果T的最長(zhǎng)邊(x, y)并非最小
那么,存在一顆生成樹(shù)R,其最長(zhǎng)邊(u, v)<(x, y),即生成樹(shù)R的任何一條邊都小于(x, y)
現(xiàn)在,采用剪切-粘帖的方法來(lái)證明T不是一顆最小生成樹(shù),即矛盾
將T中的最長(zhǎng)邊(x, y)剪切掉,這樣就得到兩顆子樹(shù)
在R中,至少存在一條邊(p, q)可以將這兩顆子樹(shù)連接起來(lái),這樣就得到:
           T - (x, y) + (p, q) < T

代碼(這里采用Kruskal算法,并查集實(shí)現(xiàn))
 1 /* union-find sets, Kruskal algorithm */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_N 1001
 6 #define MAX_M 15001
 7 struct Edge{
 8     int len;
 9     int from, to;
10 }edges[MAX_M];
11 int parent[MAX_N], rank[MAX_N];
12 int n, m;
13 
14 void
15 make_set()
16 {
17     int i;
18     for(i=1; i<=n; i++)
19         parent[i] = i;
20     memset(rank, 0sizeof(rank));
21 }
22 
23 int
24 find(int x)
25 {
26     int tmp, rt = x;
27     while(parent[rt] != rt)
28         rt = parent[rt];
29     while(x != rt) {
30         tmp = parent[x];
31         parent[x] = rt;
32         x = tmp;
33     }
34     return rt;
35 }
36 
37 void
38 Union(int x, int y)
39 {
40     int a = find(x);
41     int b = find(y);
42     if(a == b)
43         return;
44     if(rank[a] > rank[b])
45         parent[b] = a;
46     else {
47         parent[a] = b;
48         if(rank[a] == rank[b])
49             ++rank[b];
50     }
51 }
52 
53 int
54 compare(const void *arg1, const void *arg2)
55 {
56     return ((struct Edge *)arg1)->len - ((struct Edge *)arg2)->len;
57 }
58 
59 void
60 init()
61 {
62     int i;
63     for(i=0; i<m; i++
64         scanf("%d %d %d"&edges[i].from, &edges[i].to, &edges[i].len);
65     qsort(edges, m, sizeof(struct Edge), compare);
66 }
67 
68 void
69 kruskal()
70 {
71     int i, a, b, count = 0;
72     int mark[MAX_N];
73     make_set();
74     for(i=0; i<m; i++) {
75         a = find(edges[i].from);
76         b = find(edges[i].to);
77         if(a != b) {
78             mark[count++= i;
79             Union(a, b);
80         }
81     }
82     /* output */
83     printf("%d\n", edges[mark[count-1]].len);
84     printf("%d\n", count);
85     for(i=0; i<count; i++)
86         printf("%d %d\n", edges[mark[i]].from, edges[mark[i]].to);
87 }
88 
89 int
90 main(int argc, char **argv)
91 {
92     while(scanf("%d %d"&n, &m) != EOF) {
93         init();
94         kruskal();
95     }
96 }


posted @ 2010-09-05 13:09 simplyzhao 閱讀(211) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1251
http://acm.pku.edu.cn/JudgeOnline/problem?id=1258

思路:
最簡(jiǎn)單典型的最小生成樹(shù),PRIM算法
參考算法導(dǎo)論

代碼(pku 1251):
 1 /* MST problem */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_LEN 27
 6 #define INF 0x7FFFFFFF
 7 int num, min;
 8 int adj[MAX_LEN][MAX_LEN];
 9 int key[MAX_LEN], in[MAX_LEN];
10 
11 void
12 init()
13 {
14     int i, j, k, dis;
15     char tmp[2], tmp1[2];
16     memset(adj, 0sizeof(adj));
17     memset(in0sizeof(in));
18     min = 0;
19     for(i=0; i<num; i++)
20         key[i] = INF;
21     for(i=0; i<num-1; i++) {
22         scanf("%s %d", tmp, &k);
23         for(j=0; j<k; j++) {
24             scanf("%s %d", tmp1, &dis);
25             adj[tmp[0]-'A'][tmp1[0]-'A'= dis;
26             adj[tmp1[0]-'A'][tmp[0]-'A'= dis;
27         }
28     }
29 }
30 
31 void
32 prim()
33 {
34     int i, j, k, cur;
35     /* start from vertex 'A' */
36     in[0= 1;
37     for(i=1; i<num; i++)
38         if(adj[0][i])
39             key[i] = adj[0][i];
40     for(i=1; i<num; i++) { /* num-1 vertex left */
41         cur = INF;
42         for(j=0; j<num; j++) {
43             if(!in[j] && key[j]<cur) {
44                 cur = key[j];
45                 k = j;
46             }
47         }
48         min += cur;
49         in[k] = 1;
50         for(j=0; j<num; j++) {
51             if(adj[k][j]) {
52                 if(!in[j] && adj[k][j]<key[j])
53                     key[j] = adj[k][j];
54             }
55         }
56     }
57 }
58 
59 int
60 main(int argc, char **argv)
61 {
62     while(scanf("%d"&num)!=EOF && num) {
63         init();
64         prim();
65         printf("%d\n", min);
66     }
67 }

posted @ 2010-09-05 00:09 simplyzhao 閱讀(187) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=3687

思路:
這題理解起來(lái)就很困難,等理解透了也還是不會(huì)

參考:
http://hi.baidu.com/archersfate/blog/item/30e66f76734a0c12b051b9ab.html

總結(jié):
逆向的拓?fù)渑判颍韧趯?duì)轉(zhuǎn)置圖進(jìn)行正向的拓?fù)渑判颍ㄆ鋵?shí)就是入度與出度的區(qū)別)
DFS實(shí)現(xiàn)拓?fù)渑判蜻m合于求出所有可能的解
BFS實(shí)現(xiàn)拓?fù)渑判蜻m合于求出滿足特定要求的解


代碼:
 1 /* cpp: priority_queue */
 2 #include<iostream>
 3 #include<queue>
 4 #include<vector>
 5 #include<functional>
 6 #include<cstdio>
 7 #include<cstring>
 8 using namespace std;
 9 
10 #define MAX_N 201
11 int n, m;
12 int adj[MAX_N][MAX_N];
13 int out_degree[MAX_N], topo[MAX_N], ans[MAX_N];
14 
15 void
16 init()
17 {
18     int i, pre, suc;
19     memset(adj, 0sizeof(adj));
20     memset(out_degree, 0sizeof(out_degree));
21     scanf("%d %d"&n, &m);
22     for(i=0; i<m; i++) {
23         scanf("%d %d"&pre, &suc);
24         if(!adj[pre][suc]) { /* avoid duplicates */
25             adj[pre][suc] = 1;
26             ++out_degree[pre];
27         }
28     }
29 }
30 
31 void
32 reverse_topo_sort()
33 {
34     int i, tmp, count = 0;
35     priority_queue<int, vector<int>, less<int> > Q;
36     for(i=1; i<=n; i++)
37         if(out_degree[i] == 0)
38             Q.push(i);
39     while(!Q.empty()) { /* BFS */
40         tmp = Q.top();
41         Q.pop();
42         topo[++count] = tmp;
43         for(i=1; i<=n; i++)
44             if(adj[i][tmp]) {
45                 --out_degree[i];
46                 if(!out_degree[i])
47                     Q.push(i);
48             }
49     }
50     if(count != n) { /* not DAG */
51         printf("-1\n");
52         return;
53     }
54     for(i=1; i<=n; i++)
55         ans[topo[n-i+1]] = i;
56     for(i=1; i<=n; i++)
57         printf("%d ", ans[i]);
58     printf("\n");
59 }
60 
61 int
62 main(int argc, char **argv)
63 {
64     int tests;
65     scanf("%d"&tests);
66     while(tests--) {
67         init();
68         reverse_topo_sort();
69     }
70 }

轉(zhuǎn)載:
   PKU 3687 在基本的拓?fù)渑判虻幕A(chǔ)上又增加了一個(gè)要求:編號(hào)最小的節(jié)點(diǎn)要盡量排在前面;在滿足上一個(gè)條件的基礎(chǔ)上,編號(hào)第二小的節(jié)點(diǎn)要盡量排在前面;在滿足前兩個(gè)條件的基礎(chǔ)上,編號(hào)第三小的節(jié)點(diǎn)要盡量排在前面……依此類推。(注意,這和字典序是兩回事,不可以混淆。)

    如圖 1 所示,滿足要求的拓?fù)湫驊?yīng)該是:6 4 1 3 9 2 5 7 8 0。



圖 1 一個(gè)拓?fù)渑判虻睦?/div>
    一般來(lái)說(shuō),在一個(gè)有向無(wú)環(huán)圖中,用 BFS 進(jìn)行拓?fù)渑判蚴潜容^常見(jiàn)的
做法
做法,如算法 1 所示。但是它不一定能得到本題要求的拓?fù)湫颉?br style="line-height: normal; ">
1. 把所有入度為 0 的節(jié)點(diǎn)放進(jìn)隊(duì)列 Q
2. WHILE: Q 不是空隊(duì)列
3.     從 Q 中取出隊(duì)列首元素 a,把 a 添加到答案的尾部
4.     FOR:所有從 a 出發(fā)的邊 a → b
5.         把 b 的入度減 1。如果 b 的入度變?yōu)?0,則把 b 放進(jìn)隊(duì)列 Q。

算法 1 用 BFS 進(jìn)行拓?fù)渑判?/div>
    為了解決本問(wèn)題,下面讓我來(lái)探究一下拓?fù)湫虻囊恍┬再|(zhì)。以圖 1 為例,節(jié)點(diǎn) 0 毫無(wú)疑問(wèn)排在最后。除了節(jié)點(diǎn) 0 以外,有三條互相平行的路徑:6 → 4 → 1、 3→ 9 → 2 和 5 → 7 → 8。一條路徑上的各個(gè)節(jié)點(diǎn)的先后關(guān)系都是不能改變的,比如路徑 6 → 4 → 1 上的三個(gè)節(jié)點(diǎn)在拓?fù)湫蛑校欢ㄊ?nbsp;6 在最前,1 在最后。但是,互相平行的各條路徑,在總的拓?fù)湫蛑?strong style="line-height: normal; ">任意交錯(cuò)都是合法的。比如,以下都是圖 1 的合法拓?fù)湫颍?br style="line-height: normal; ">
    6 4 1 3 9 2 5 7 8 0、 3 6 9 4 5 1 7 8 2 0、 5 6 4 7 3 8 1 9 2 0、 3 5 6 4 1 7 9 2 8 0、 6 5 7 8 4 3 9 2 1 0。

    怎么才能找出題目要求的拓?fù)湫蚰兀吭谶@里,我想用字典序最先的拓?fù)湫騺?lái)引出這個(gè)算法。算法 2 可以求出字典序最先的拓?fù)湫颉?br style="line-height: normal; ">
1. 把所有入度為 0 的節(jié)點(diǎn)放進(jìn)優(yōu)先隊(duì)列 PQ
2. WHILE: PQ 不是空隊(duì)列
3. 從 PQ 中取出編號(hào)最小的元素 a,把 a 添加到答案的尾部
4. FOR:所有從 a 出發(fā)的邊 a → b
5. 把 b 的入度減 1。如果 b 的入度變?yōu)?0,則把 b 放進(jìn)優(yōu)先隊(duì)列 PQ。

算法 2 求出字典序最先的拓?fù)湫?/div>
    可見(jiàn),算法 2 和算法 1 基本一樣,只是把隊(duì)列改成了優(yōu)先隊(duì)列。用它求出的圖 1 的字典序最先的拓?fù)湫驗(yàn)椋?font color="#339900" style="line-height: normal; ">3 5 6 4 1 7 8 9 2 0。但是這顯然不是本題要求的答案,因?yàn)楣?jié)點(diǎn) 1 的位置還不夠靠前。

    算法 2 可以算是一個(gè)貪心算法,每一步都找編號(hào)最小的節(jié)點(diǎn)。但是對(duì)于圖 1 中的三條路徑,頭的編號(hào)比較小的,不一定要先出隊(duì)列。正確的步驟應(yīng)該如下:
  1. 節(jié)點(diǎn) 0 的位置是鐵定在最后的,不用考慮。只考慮剩下的三條路徑。
  2. 先找編號(hào)最小的,節(jié)點(diǎn) 1。把它和它所在的路徑中位于它前面的節(jié)點(diǎn)全部拿出來(lái)。目前的答案是 6 4 1,這樣, 節(jié)點(diǎn) 1 就盡量靠前了。
  3. 再找剩下的節(jié)點(diǎn)中編號(hào)最小的,節(jié)點(diǎn) 2。把它和它所在的路徑中位于它前面的節(jié)點(diǎn)全部拿出來(lái)。目前的答案是 6 4 1 3 9 2 ,這樣,節(jié)點(diǎn) 2 就盡量靠前了。
  4. 只剩下一條路徑了,只能依次把其中的節(jié)點(diǎn)拿出來(lái)。最后答案就是 6 4 1 3 9 2 5 7 8 0。
    顯然,算法 2 的貪心策略對(duì)于這個(gè)問(wèn)題是不可行的。不能著眼于每條路徑的頭,而是要找編號(hào)最小的節(jié)點(diǎn)在哪條路徑上,優(yōu)先把這條路徑拿出來(lái)。但問(wèn)題在于,在 BFS 的過(guò)程中,我們只能看到每條路徑的頭,看不到后面的節(jié)點(diǎn),這該怎么辦呢?

    讓我們換個(gè)角度想一想,節(jié)點(diǎn) 3 和 6,應(yīng)該是 6 先出隊(duì)列,因?yàn)楣?jié)點(diǎn) 1 在 6 的后面。這和節(jié)點(diǎn) 3 和 6 的編號(hào)大小沒(méi)有任何關(guān)系。但是,再看另外兩條路徑的尾部,節(jié)點(diǎn) 2 和 8,可以肯定地說(shuō),2 一定先出隊(duì)列,因?yàn)樗鼈兒竺娑紱](méi)有別的節(jié)點(diǎn)了,這個(gè)時(shí)候完全以這兩個(gè)節(jié)點(diǎn)本身的編號(hào)大小決定順序。歸納起來(lái)就是說(shuō),對(duì)于若干條平行的路徑,小的頭部不一定排在前面,但是大的尾部一定排在后面。于是,就有了算法 3

1. 把所有出度為 0 的節(jié)點(diǎn)放進(jìn)優(yōu)先隊(duì)列 PQ
2. WHILE: PQ 不是空隊(duì)列
3. 從 PQ 中取出編號(hào)最大的元素 a,把 a 添加到答案的頭部
4.     FOR:所有指向 a 的邊 b → a
5.     把 b 的出度減 1。如果 b 的出度變?yōu)?0,則把 b 放進(jìn)優(yōu)先隊(duì)列 PQ。

算法 3 求出本題目要求的拓?fù)湫?/div>
    我覺(jué)得這道題目確實(shí)挺奧妙的,我搞了很久才想通算法 3 為什么是正確的,特地在此寫(xiě)一下。
posted @ 2010-09-04 11:35 simplyzhao 閱讀(304) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1664

思路:
就是根據(jù)題意進(jìn)行DFS,要注意的是如何避免重復(fù): 所放蘋(píng)果數(shù)目遞減
居然一會(huì)就AC了哈哈,暑假的鍛煉還是有些成果的:)

代碼:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int n, m;
 5 int total;
 6 
 7 void
 8 dfs(int level, int left, int last)
 9 {
10     int i, up;
11     if(level==n) {
12         if(left == 0)
13             ++total;
14         return;
15     }
16     up = left<last ? left : last;
17     for(i=up; i>=0; i--)
18         dfs(level+1, left-i, i);
19 }
20 
21 int
22 main(int argc, char **argv)
23 {
24     int tests;
25     scanf("%d"&tests);
26     while(tests--) {
27         scanf("%d %d"&m, &n);
28         total = 0;
29         dfs(0, m, m);
30         printf("%d\n", total);
31     }
32 }
posted @ 2010-09-03 22:48 simplyzhao 閱讀(292) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1128

思路:
想法是有:先找出沒(méi)有被任何其他frame覆蓋的frame,然后將該frame進(jìn)行標(biāo)記,使之匹配任何字母,然后重復(fù)以上過(guò)程
不過(guò),程序不知道該如何寫(xiě)

參考discuss以及其他人思路,發(fā)現(xiàn)可以用拓?fù)渑判騺?lái)做(拓?fù)渑判颍瑓⒖妓惴▽?dǎo)論)
如何根據(jù)輸入來(lái)建立鄰接矩陣比較有意思,另外根據(jù)各個(gè)頂點(diǎn)的入度DFS實(shí)現(xiàn)拓?fù)渑判?br>
代碼:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #define MAX_LEN 31
  5 #define MAX_NUM 27
  6 char map[MAX_LEN][MAX_LEN];
  7 int n, m;
  8 int adj[MAX_NUM][MAX_NUM], num, in[MAX_NUM], visited[MAX_NUM];
  9 int x1, y1, x2, y2;
 10 
 11 void
 12 search(char ch)
 13 {
 14     int i, j;
 15     x1 = y1 = MAX_LEN;
 16     x2 = y2 = -1;
 17     for(i=0; i<n; i++)
 18         for(j=0; j<m; j++)
 19             if(map[i][j] == ch) {
 20                 if(i<x1) x1 = i;
 21                 if(i>x2) x2 = i;
 22                 if(j<y1) y1 = j;
 23                 if(j>y2) y2 = j;
 24             }
 25 }
 26 
 27 void
 28 build_graph()
 29 {
 30     int i, j, k;
 31     char ch;
 32     num = 0;
 33     memset(adj, 0sizeof(adj));
 34     memset(in-1sizeof(in));
 35     for(i=0; i<n; i++) {
 36         for(j=0; j<m; j++) {
 37             if(map[i][j]=='.' || in[map[i][j]-'A']>-1)
 38                 continue;
 39             in[map[i][j]-'A'= 0;
 40             ++num;
 41             search(map[i][j]);
 42             for(k=x1; k<=x2; k++) {
 43                 ch = map[k][y1];
 44                 if(ch != map[i][j])
 45                     adj[map[i][j]-'A'][ch-'A'= 1;
 46             }
 47             for(k=x1; k<=x2; k++) {
 48                 ch = map[k][y2];
 49                 if(ch != map[i][j])
 50                     adj[map[i][j]-'A'][ch-'A'= 1;
 51             }
 52             for(k=y1; k<=y2; k++) {
 53                 ch = map[x1][k];
 54                 if(ch != map[i][j])
 55                     adj[map[i][j]-'A'][ch-'A'= 1;
 56             }
 57             for(k=y1; k<=y2; k++) {
 58                 ch = map[x2][k];
 59                 if(ch != map[i][j])
 60                     adj[map[i][j]-'A'][ch-'A'= 1;
 61             }
 62         }
 63     }
 64     for(i=0; i<MAX_NUM; i++)
 65         for(j=0; j<MAX_NUM; j++)
 66             if(adj[i][j])
 67                 ++in[j]; /* in-degree */
 68 }
 69 
 70 void
 71 topological_sort(char *str, int level)
 72 {
 73     int i, j;
 74     if(level == num) {
 75         printf("%s\n", str);
 76         return;
 77     }
 78     for(i=0; i<MAX_NUM; i++) {
 79         if(in[i]==0 && !visited[i]) {
 80             str[level] = 'A'+i;
 81             visited[i] = 1;
 82             for(j=0; j<MAX_NUM; j++)
 83                 if(adj[i][j])
 84                     --in[j];
 85             topological_sort(str, level+1);
 86             visited[i] = 0;
 87             for(j=0; j<MAX_NUM; j++)
 88                 if(adj[i][j])
 89                     ++in[j];
 90         }
 91     }
 92 }
 93 
 94 int
 95 main(int argc, char **argv)
 96 {
 97     int i;
 98     char str[MAX_NUM];
 99     while(scanf("%d %d"&n, &m)!=EOF) {
100         for(i=0; i<n; i++)
101             scanf("%s", map[i]);
102         build_graph();
103         memset(str, 0sizeof(str));
104         memset(visited, 0sizeof(visited));
105         topological_sort(str, 0);
106     }
107 }
posted @ 2010-09-03 16:42 simplyzhao 閱讀(289) | 評(píng)論 (0)編輯 收藏
問(wèn)題:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1324

參考:
http://hi.baidu.com/aekdycoin/blog/item/08774afbd1a29316a8d31111.html
http://clover520.blogbus.com/logs/38001465.html

思路:
用BFS求最短路徑肯定是沒(méi)有問(wèn)題的,關(guān)鍵是狀態(tài)如何表示
參考別人的思路,原來(lái)蛇身只需要通過(guò)上、下、左、右四個(gè)方向表示即可(兩bits或4進(jìn)制),這樣可以很大程度上減少空間,而且判重也就不再是個(gè)問(wèn)題,只需要用三維數(shù)組表示即可
不過(guò)我自己寫(xiě)出來(lái)的代碼卻總是MLE,悲劇...(無(wú)奈,貼了別人代碼過(guò)的,無(wú)恥啊)

代碼:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 
 5 int kk[4][2]={1,0,0,1,0,-1,-1,0},N,M,L;
 6 struct point{
 7     char x,y;
 8     int dis,body;
 9 };
10 int bfs();
11 int main(){
12     int Cas=0;
13     while(scanf("%d%d%d",&N,&M,&L)==3){
14         if(N==0&&M==0&&L==0)break;
15         printf("Case %d: %d\n",++Cas,bfs());
16     }
17     return 0;
18 }
19 char viss[20][20][1<<14];
20 int vis(struct point* t){
21     int ans=0,i=0;
22     if(viss[t->x][t->y][t->body])return 1;
23     viss[t->x][t->y][t->body]=1;
24     return 0;
25 }
26 char map[20][20],mapt[20][20];
27 char valid(int x,int y){
28     if(x<0||x>=N||y<0||y>=M||mapt[x][y])return 0;
29     return 1;
30 }
31 struct point Q[20*20*(1<<14)];
32 int head,tail;
33 int bfs(){
34     int x,y,lx,ly,i,k,nx,ny;
35     struct point t,now;
36     memset(viss,0,sizeof(viss));
37     scanf("%d%d",&lx,&ly);
38     t.x=lx-1;t.y=ly-1;t.dis=0;t.body=0;
39     for(i=1;i<L;++i){
40         scanf("%d%d",&x,&y);
41         for(k=0;k<4;++k)if(lx+kk[k][0]==x&&ly+kk[k][1]==y)break;
42         t.body|=k<<((i-1)<<1);
43         lx=x;ly=y;
44     }
45     memset(map,0,sizeof(map));
46     scanf("%d",&k);
47     for(i=0;i<k;++i){
48         scanf("%d%d",&x,&y);
49         map[x-1][y-1]=1;
50     }
51     head=tail=0;
52     Q[tail++]=t;
53     vis(&t);
54     while(head!=tail){
55         now=Q[head++];
56         if(now.x==0&&now.y==0)return now.dis;
57         
58         memcpy(mapt,map,sizeof(map));
59         mapt[x=now.x][y=now.y]=1;
60         int s=now.body;
61         for(i=1;i<L;++i,s>>=2){
62             k=s&3;
63             mapt[x=x+kk[k][0]][y=y+kk[k][1]]=1;
64         }
65         
66         for(k=0;k<4;++k){
67             if(!valid(nx=now.x+kk[k][0],ny=now.y+kk[k][1]))continue;
68             t.x=nx,t.y=ny;
69             t.body=((now.body<<2)|(3-k))&((1<<((L-1)<<1))-1);
70             t.dis=now.dis+1;
71             if(!vis(&t)){
72                 Q[tail++]=t;
73             }
74         }
75     }
76     return -1;
77 }
posted @ 2010-09-03 10:05 simplyzhao 閱讀(342) | 評(píng)論 (0)編輯 收藏
僅列出標(biāo)題
共21頁(yè): First 9 10 11 12 13 14 15 16 17 Last 

導(dǎo)航

<2011年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

統(tǒng)計(jì)

  • 隨筆 - 209
  • 文章 - 0
  • 評(píng)論 - 7
  • 引用 - 0

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              欧美**人妖| 久久久夜精品| 在线综合视频| 亚洲第一级黄色片| 99精品久久久| 欧美专区在线观看一区| 99国产精品久久久久久久| 欧美成人久久| 亚洲精品免费在线| 亚洲第一视频网站| 欧美精品在线观看播放| 日韩一级片网址| 亚洲一区二区三区国产| 韩日欧美一区二区| 亚洲经典一区| 国产精品亚洲成人| 美女图片一区二区| 欧美成人三级在线| 欧美一区1区三区3区公司| 亚洲精品日韩综合观看成人91| 国产精品久久久久久久久搜平片 | 欧美日韩中文字幕综合视频| 亚洲无亚洲人成网站77777| 亚洲综合另类| 亚洲精选大片| 久久精品一本久久99精品| 亚洲国产成人精品女人久久久 | 亚洲一区二区在线播放| 免费永久网站黄欧美| 午夜精品一区二区三区电影天堂| 欧美日韩一区二区三区四区在线观看 | 亚洲一区二区三区成人在线视频精品 | 欧美成人免费观看| 久久久久久久久岛国免费| 久久av二区| 亚洲精品久久| 欧美电影专区| 亚洲精品老司机| 亚洲人妖在线| 欧美日韩国产经典色站一区二区三区| 久久久久国内| 激情欧美日韩| 欧美成年人网站| 亚洲高清一区二| 一区二区久久| 国产伦精品一区二区三区| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲私人影吧| 国产亚洲aⅴaaaaaa毛片| 久久国产精品久久久| 久久综合色播五月| 亚洲精品美女久久久久| 欧美日韩高清在线| 欧美在线播放高清精品| 欧美激情片在线观看| 亚洲一区二区三区免费视频| 国产精品黄页免费高清在线观看| 欧美在线免费看| 亚洲精品国产无天堂网2021| 欧美在线3区| 日韩午夜在线电影| 国内揄拍国内精品久久| 欧美另类视频在线| 久久久精品tv| 亚洲一二三四久久| 欧美激情亚洲| 久久人人97超碰精品888| 亚洲一区二区三区四区中文| 亚洲免费av片| 免费短视频成人日韩| 一区二区国产日产| 亚洲国产精品成人久久综合一区 | 亚洲网站视频福利| 黄色成人在线| 国产乱码精品一区二区三区忘忧草| 久久这里有精品视频| 欧美在线视频观看免费网站| 亚洲性感美女99在线| 夜夜爽www精品| 99国产精品久久久久久久成人热| 欧美91大片| 欧美高清你懂得| 国产精品丝袜91| 欧美1区2区3区| 免费av成人在线| 欧美成人精品| 亚洲国产精品一区二区三区| 久久久亚洲人| 亚洲国产精品福利| 亚洲狼人精品一区二区三区| 99国产精品99久久久久久粉嫩 | 亚洲一区二区三区中文字幕在线| 一区二区三区四区五区精品| 夜夜精品视频一区二区| 欧美在线日韩| 免费视频一区| 久久久久久一区二区三区| 暖暖成人免费视频| 亚洲精品网址在线观看| 制服丝袜亚洲播放| 欧美一区二区国产| 欧美国产亚洲视频| 国产美女精品一区二区三区| 雨宫琴音一区二区在线| 亚洲视频精选| 久久综合色婷婷| 亚洲免费电影在线观看| 亚洲欧美国产一区二区三区| 久久精品五月婷婷| 亚洲激情一区二区三区| 亚洲女优在线| 欧美日韩精品在线播放| 亚洲电影第三页| 性欧美1819sex性高清| 亚洲欧洲精品一区二区精品久久久| 亚洲一区三区视频在线观看| 欧美精品麻豆| 亚洲精品视频在线| 欧美 亚欧 日韩视频在线| 亚洲欧美制服中文字幕| 欧美日韩精品| 这里只有精品视频在线| 91久久精品国产91性色| 欧美jizz19性欧美| 亚洲国产网站| 亚洲欧洲午夜| 欧美日本高清视频| 一区二区三区视频在线观看| 亚洲精品国产精品国产自| 欧美99久久| 日韩天天综合| 一本一道久久综合狠狠老精东影业 | 亚洲午夜精品一区二区| 欧美三日本三级少妇三2023| 一级成人国产| 亚洲一区在线视频| 很黄很黄激情成人| 亚洲国产cao| 国产精品久久午夜夜伦鲁鲁| 久久久综合网| 欧美国产极速在线| 亚洲日本成人| 精品成人在线观看| 免费看亚洲片| 亚洲人成在线观看| 欧美色另类天堂2015| 久久久久亚洲综合| 欧美日本中文| 美女国内精品自产拍在线播放| 久久影视三级福利片| 午夜日韩在线| 欧美激情按摩| 美女任你摸久久| 国产精品美女999| 亚洲国产成人久久| 国产一区二区三区免费在线观看 | 日韩视频在线观看一区二区| 亚洲影院污污.| 夜夜嗨网站十八久久| 久久精品99无色码中文字幕 | 伊人精品成人久久综合软件| 亚洲一区不卡| 亚洲天堂av在线免费| 欧美国产日韩二区| 亚洲国产精品成人va在线观看| 国产一区二区三区四区在线观看| 一区二区三区波多野结衣在线观看| 亚洲国产高清在线| 欧美成人dvd在线视频| 女同一区二区| 日韩网站在线观看| 欧美日韩国产123| 91久久黄色| 香蕉成人伊视频在线观看 | 欧美精品日韩www.p站| 亚洲福利国产| 欧美日韩专区| 亚洲深夜福利在线| 欧美一区二区日韩| 国产视频亚洲精品| 久热这里只精品99re8久| 亚洲国内自拍| 亚洲香蕉伊综合在人在线视看| 欧美午夜电影在线观看| 久久超碰97人人做人人爱| 欧美成人免费一级人片100| 一本大道av伊人久久综合| 中文在线不卡| 玖玖综合伊人| 亚洲欧美日本国产专区一区| 国产人成精品一区二区三| 久久久亚洲高清| 一二三区精品福利视频| 久久综合伊人| 欧美一站二站| 夜夜嗨av色综合久久久综合网 | 欧美大尺度在线| 亚洲欧美日韩天堂| 亚洲乱码久久| 亚洲大黄网站|