您的位置:首页 > 其它

新队员图论基础_【CSUST_12级训练】

2013-05-23 21:13 351 查看
新队员图论基础

背景:2013/05/05 去农大水了下蓝桥,估计是去了就有奖,吸引学生参赛,任然被虐!!!
           2013/05/11 惨败于湘潭邀请赛。
          最近一直纠结与考研还是工作,六级一直又没过,荒废了一段时间,今天就来新生这儿水一下找点做题的心情 
     吧。
          无论是比赛还是平时训练,果断被12级的虐了Orz,努力不够+。。。

  IDOriginTitle
 4 / 7Problem AHDU 1232并查集
 3 / 4Problem BHDU 1856并查集
 1 / 3Problem CHDU 1874Floyd
 1 / 1Problem DHDU 2544Floyd || Dijkstra
  Problem EHDU 2066Dijkstra
  Problem FHDU 2112map + 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时,输入结束,该用例不被处理。 

 

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
998

HintHint
Huge input, scanf is recommended.

 

Source

浙大计算机研究生复试上机考试-2005年

 

Recommend

JGShining

AAccepted232 KB15 msC++720 B2013-05-23 19:20:32
#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.

 

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
2

Hint
A 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

HDU 2007 Programming Contest - Final

 

Recommend

lcy

BAccepted78584 KB328 msC++781 B2013-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),分别代表起点和终点。

 

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

2008浙大研究生复试热身赛(2)——全真模拟

 

Recommend

lcy

 
CAccepted312 KB46 msC++1003 B2013-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;
}

CAccepted316 KB0 msC++1136 B2013-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条商店到赛场的路线。

 

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

UESTC 6th Programming Contest Online

 

Recommend

lcy

 

DAccepted276 KB31 msC++892 B2013-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]
);

}
return 0;
}

DAccepted276 KB15 msC++1055 B2013-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
);
}
return 0;
}


E 题题解见下一篇博客 :hdu 2066 一个人的旅行【Dijkstra
12级新生训练—图论E】

F 题题解见下下篇博客: 


hdu 2112 Today【F - map + Floyd - 入门训练】

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: