背景:2013/05/05 去农大水了下蓝桥,估计是去了就有奖,吸引学生参赛,任然被虐!!!
2013/05/11 惨败于湘潭邀请赛。
最近一直纠结与考研还是工作,六级一直又没过,荒废了一段时间,今天就来新生这儿水一下找点做题的心情
吧。
无论是比赛还是平时训练,果断被12级的虐了Orz,努力不够+。。。
ID | Origin | Title | ||
---|---|---|---|---|
4 / 7 | Problem A | HDU 1232 | 并查集 | |
3 / 4 | Problem B | HDU 1856 | 并查集 | |
1 / 3 | Problem C | HDU 1874 | Floyd | |
1 / 1 | Problem D | HDU 2544 | Floyd || Dijkstra | |
Problem E | HDU 2066 | Dijkstra | ||
Problem F | HDU 2112 | map + Floyd |
畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 21422 Accepted Submission(s): 11116
Problem Description
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。
Sample Input
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
Sample Output
1 0 2 998Huge input, scanf is recommended.HintHint
Source
Recommend
JGShining
#include<stdio.h> const int maxn = 1000+10; int f[maxn]; int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); } void Union(int x, int y) { int fx = find(x); int fy = find(y); if(fx == fy) return; f[fx] = fy; } int main() { int n,m; while(scanf("%d", &n) != EOF) { if(n == 0) break; scanf("%d", &m); for(int i = 0; i <= n; i++) { f[i] = i; } int u, v; while(m--) { scanf("%d%d", &u, &v); Union(u, v); } int root = -1; for(int i = 1; i <= n; i++) { if(f[i] == i) root++; } printf("%d\n", root); } return 0; }
More is better
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 327680/102400 K (Java/Others)Total Submission(s): 8956 Accepted Submission(s): 3346
Problem Description
Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.
Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
Input
The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
Output
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
Sample Input
4 1 2 3 4 5 6 1 6 4 1 2 3 4 5 6 7 8
Sample Output
4 2HintA and B are friends(direct or indirect), B and C are friends(direct or indirect), then A and C are also friends(indirect). In the first sample {1,2,5,6} is the result. In the second sample {1,2},{3,4},{5,6},{7,8} are four kinds of answers.
Author
lxlcrystal@TJU
Source
Recommend
lcy
B | Accepted | 78584 KB | 328 ms | C++ | 781 B | 2013-05-23 19:38:18 |
#include<stdio.h> #include<algorithm> using namespace std; const int maxn = 10000000+10; int p[maxn]; int r[maxn]; int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); } void Union(int x, int y) { int fx = find(x); int fy = find(y); if(fx == fy) return; p[fx] = fy; r[fy] += r[fx]; } void set() { for(int x = 0; x < maxn; x++) { p[x] = x; r[x] = 1; } } int main() { int n; while(scanf("%d", &n) != EOF) { set(); int x, y; while(n--) { scanf("%d%d", &x, &y); Union(x, y); } int ans = 0; for(int i = 0; i < maxn; i++) { ans = max(ans,r[i]); } printf("%d\n", ans); } return 0; }
畅通工程续
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18225 Accepted Submission(s): 6299
Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
Sample Output
2 -1
Author
linle
Source
Recommend
lcy
C | Accepted | 312 KB | 46 ms | C++ | 1003 B | 2013-05-23 20:11:02 |
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn = 210; const int INF = 2000000+10; int n,m; int d[maxn][maxn]; void floyd() { for(int k = 0; k < n; k++) { for(int i = 0; i < n; i ++) { for(int j = 0; j < n; j++) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); //d[j][i] = d[i][j];//反正会遍历到,有没这句一样AC } } } } int main() { while(scanf("%d%d", &n,&m) != EOF) { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) d[i][j] = (i == j ? 0 : INF); } int x, y, w; while(m--) { scanf("%d%d%d", &x, &y, &w); d[x][y] = min(d[x][y], w); ////// d[y][x] = d[x][y]; } floyd(); int start,end; scanf("%d%d", &start,&end); if(d[start][end] == INF) printf("-1\n"); else printf("%d\n", d[start][end]); } return 0; }
C | Accepted | 316 KB | 0 ms | C++ | 1136 B | 2013-05-23 20:27:44 |
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn = 210; const int INF = 2000000+10; int map[maxn][maxn]; int d[maxn]; bool vis[maxn]; int n,m; int start, end; void Dijkstra() { memset(vis, false, sizeof(vis)); for(int i = 0; i < n; i++) d[i] = (i == start ? 0 : INF); for(int i = 0; i < n; i++) { int x, m = INF; for(int y = 0; y < n; y++) if(!vis[y] && d[y] <= m) m = d[x=y]; vis[x] = true; for(int y = 0; y < n; y++) d[y] = min(d[y], d[x]+map[x][y]); } } int main() { while(scanf("%d%d", &n,&m) != EOF) { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) map[i][j] = (i == j ? 0 : INF); } int x, y, w; while(m--) { scanf("%d%d%d", &x, &y, &w); if(w < map[x][y]) { map[x][y] = w; map[y][x] = w; } } scanf("%d%d", &start, &end); Dijkstra(); if(d[end] == INF) printf("-1\n"); else printf("%d\n", d[end]); } return 0; }
最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 20021 Accepted Submission(s): 8560
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
Sample Output
3 2
Source
Recommend
lcy
D | Accepted | 276 KB | 31 ms | C++ | 892 B | 2013-05-23 20:42:00 |
#include<stdio.h> #include<algorithm> using namespace std; const int maxn = 110; const int INF = 1000000+10; int d[maxn][maxn]; int n,m; void floyd() { for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { d[i][j] = min(d[i][j], d[i][k]+d[k][j]); } } } } int main() { while(scanf("%d%d", &n, &m) != EOF) { if(n == 0) break; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) d[i][j] = (i == j ? 0 : INF); } int x,y,w; while(m--) { scanf("%d%d%d", &x,&y,&w); if(w < d[x][y]) { d[x][y] = w; d[y][x] = w; } } floyd(); printf("%d\n", d[1][n]); } return 0; }
D | Accepted | 276 KB | 15 ms | C++ | 1055 B | 2013-05-23 20:50:17 |
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn = 110; const int INF = 1000000+10; int map[maxn][maxn]; int d[maxn]; bool vis[maxn]; int n,m; void Dijkstra() { memset(vis, false, sizeof(vis)); for(int i = 1; i <= n; i++) d[i] = (i == 1 ? 0 : INF); for(int i = 0; i < n; i++) { int x,m = INF; for(int y = 1; y <= n; y++) if(!vis[y] && d[y] <= m) m = d[x=y]; vis[x] = true; for(int y = 1; y <= n; y++) d[y] = min(d[y], d[x]+map[x][y]); } } int main() { while(scanf("%d%d", &n,&m) != EOF) { if(n == 0) break; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) map[i][j] = (i == j ? 0 : INF); } int x,y,w; while(m--) { scanf("%d%d%d", &x,&y,&w); if(w < map[x][y]) { map[x][y] = w; map[y][x] = w; } } Dijkstra(); printf("%d\n", d[n]); } return 0; }
F 题题解见下下篇博客: