感觉 差不多了,那题bfs + 最小生成树的,待我以后再补上,感觉最小生成树,应该有一定的理解了吧、、、、
还有 到底是prim 还是 prime 啊 - -#
A - Jungle Roads
Description
The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages. The villages are labeled A through I in the maps above. The map on the right shows the roads that could be maintained most cheaply, for 216 aacms per month. Your task is to write a program that will solve such problems.
Input
Output
Sample Input
9 A 2 B 12 I 25 B 3 C 10 H 40 I 8 C 2 D 18 G 55 D 1 E 44 E 2 F 60 G 38 F 0 G 1 H 35 H 1 I 35 3 A 2 B 10 C 40 B 1 C 20 0
Sample Output
216 30
一开始以为输入麻烦不想做,其实还是挺简单的、、、
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <string.h>
using namespace std;
#define N 110
#define Max 0x3fffffff
int tt[N][N];
int vis[N];
int dis[N];
int n, m;
int prim()
{
int i, j, k;
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dis[i] = tt[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
if(min == Max)
break;
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > tt[t][k])
dis[k] = tt[t][k];
}
}
return ans;
}
void init()
{
for(int i = 0; i <= n; i ++)
{
for(int j = 0; j <= n; j ++)
{
if(i == j)
tt[i][j] = 0;
else
tt[i][j] = Max;
}
}
}
int main()
{
char t[10];
char t1[10];
int a, b;
while(~scanf("%d",&n), n)
{
init();
for(int i = 0; i < n - 1; i ++)
{
scanf("%s%d",t, &a);
int tmp_1 = t[0] - 'A' + 1;
//printf("%s%d",t,a);
for(int j = 0; j < a; j ++)
{
scanf("%s%d",t1, &b);
int tmp_2 = t1[0] -'A' + 1;
tt[tmp_1][tmp_2] = b;
tt[tmp_2][tmp_1] = b;
//printf("%c %c %d \n",t[0],t1[0] ,tt[tmp_1][tmp_2]);
}
//printf("\n");
}
printf("%d\n",prim());
}
}
B - Networking
Description
Your task is to design the network for the area, so that there is a connection (direct or indirect) between every two points (i.e., all the points are interconnected, but not necessarily by a direct cable), and that the total length of the used cable is minimal.
Input
The maximal number of points is 50. The maximal length of a given route is 100. The number of possible routes is unlimited. The nodes are identified with integers between 1 and P (inclusive). The routes between two points i and j may be given as i j or as j i.
Output
Sample Input
1 0 2 3 1 2 37 2 1 17 1 2 68 3 7 1 2 19 2 3 11 3 1 7 1 3 5 2 3 89 3 1 91 1 2 32 5 7 1 2 5 2 3 7 2 4 8 4 5 11 3 5 10 1 5 6 4 2 12 0
Sample Output
0 17 16 26
#include<stdio.h>
#include<string.h>
#define Max 1000000
int ans;
int map[110][110];
int dis[110];
int vis[110];
int n;
int prim()
{
int i, j, k;
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
if(min == Max)
break;
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > map [t][k])
dis[k] = map[t][k];
}
}
return ans;
}
void init(int n)
{
for(int i = 0; i <= n; i ++)
{
for(int j = 0; j <= n; j ++)
{
if(i == j)
{
map[i][j] = 0;
continue;
}
map[i][j] = Max;
}
}
}
int main()
{
int i;
int a, b, c;
int m;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
init(n);
for(i = 0; i < m; i ++)
{
scanf("%d%d%d", &a, &b, &c);
if(map[a][b] > c)
{
map[a][b] = c;
map[b][a] = c;
}
}
printf("%d\n",prim());
}
return 0;
}
D - Constructing Roads
Description
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
Input
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
Output
Sample Input
3 0 990 692 990 0 179 692 179 0 1 1 2
Sample Output
179
先输入一组表示 点与点之间的距离,后面一组是表示该两点之间存在桥,所以只需要置零即可。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
#define N 120
#define Max 1 << 29
int vis[N];
int dis[N];
int map[N][N];
int n, m;
int prime()
{
int i, j, k;
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
if(min == Max)
break;
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > map [t][k])
dis[k] = map[t][k];
}
}
return ans;
}
void init()
{
for(int i = 0; i <= n; i ++)
{
for(int j = 0; j <= n; j ++)
{
if(i == j)
map[i][j] = 0;
else
map[i][j] = Max;
}
}
}
int main()
{
int a, b;
while(~scanf("%d",&n))
{
init();
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
scanf("%d",&map[i][j]);
}
}
scanf("%d",&m);
for(int i = 0; i < m; i ++)
{
scanf("%d%d",&a,&b);
map[a][b] = map[b][a] = 0;
}
printf("%d\n",prime());
}
}
H - Highways
Description
Flatopian towns are numbered from 1 to N and town i has a position given by the Cartesian coordinates (xi, yi). Each highway connects exaclty two towns. All highways (both the original ones and the ones that are to be built) follow straight lines, and thus their length is equal to Cartesian distance between towns. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.
The Flatopian government wants to minimize the cost of building new highways. However, they want to guarantee that every town is highway-reachable from every other town. Since Flatopia is so flat, the cost of a highway is always proportional to its length. Thus, the least expensive highway system will be the one that minimizes the total highways length.
Input
The first line of the input file contains a single integer N (1 <= N <= 750), representing the number of towns. The next N lines each contain two integers, xi and yi separated by a space. These values give the coordinates of i th town (for i from 1 to N). Coordinates will have an absolute value no greater than 10000. Every town has a unique location.
The next line contains a single integer M (0 <= M <= 1000), representing the number of existing highways. The next M lines each contain a pair of integers separated by a space. These two integers give a pair of town numbers which are already connected by a highway. Each pair of towns is connected by at most one highway.
Output
If no new highways need to be built (all towns are already connected), then the output file should be created but it should be empty.
Sample Input
9 1 5 0 0 3 2 4 5 5 1 0 4 5 2 1 2 5 3 3 1 3 9 7 1 2
Sample Output
1 6 3 7 4 9 5 7 8 3
这题是要求,还需要建立哪些桥,一开始用kruskal,半天搞不出来,后来转prim 了, 恶心了我好久,下次有空再看吧。。。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
#define N 800
#define Max 0x3fffffff
int n, m;
int x[N];
int y[N];
int dis[N];
int vis[N];
int map[N][N];
int path[N];
void prim()
{
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
path[i] = 1;
}
vis[1] = 1;
for(int i = 1; i < n; i ++)
{
min = Max;
for(int j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
//if(min == Max)
// break;
ans += min;
vis[t] = 1;
if(map[path[t]][t] != 0)
printf("%d %d\n", t, path[t]);
for(int k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > map [t][k])
{
dis[k] = map[t][k];
path[k] = t;
}
}
}
}
void init()
{
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
if(i == j)
{
map[i][j] = 0;
}
else
map[i][j] = Max;
}
}
}
int main()
{
int a, b;
while(~scanf("%d",&n))
{
init();
for(int i = 1; i <= n; i ++)
{
scanf("%d%d",&x[i],&y[i]);
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
map[i][j] = (x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i]- y[j]);
map[j][i] = map[i][j];
}
}
scanf("%d",&m);
for(int i = 1; i <= m; i ++)
{
scanf("%d%d",&a, &b);
map[a][b] = map[b][a] = 0;
}
prim();
}
}
I - Agri-Net
Description
Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.
Input
The input includes several cases. For each case, the first line contains the number of farms, N (3 <= N <= 100). The following lines contain the N x N conectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.
Output
For each case, output a single integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.
Sample Input
40 4 9 214 0 8 179 8 0 1621 17 16 0
Sample Output
28
Description
Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.
Input
The input includes several cases. For each case, the first line contains the number of farms, N (3 <= N <= 100). The following lines contain the N x N conectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.
Output
For each case, output a single integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.
Sample Input
40 4 9 214 0 8 179 8 0 1621 17 16 0
Sample Output
28
纯 模版
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
#define N 120
#define Max 1 << 29
int vis[N];
int dis[N];
int map[N][N];
int n;
int prime()
{
int i, j, k;
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
if(min == Max)
break;
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > map [t][k])
dis[k] = map[t][k];
}
}
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
scanf("%d",&map[i][j]);
}
}
printf("%d\n",prime());
}
}
L - 还是畅通工程
Description
Input
当N为0时,输入结束,该用例不被处理。
Output
Sample Input
3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0
Sample Output
3 5
Hint
简单的中文模版题!!
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
#define N 120
#define Max 1 << 29
int vis[N];
int dis[N];
int map[N][N];
int n;
int prime()
{
int i, j, k;
int ans = 0;
int min, t;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && dis[j] < min)
{
min = dis[j];
t = j;
}
}
if(min == Max)
break;
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] > map [t][k])
dis[k] = map[t][k];
}
}
return ans;
}
int main()
{
int a, b, c;
while(~scanf("%d",&n))
{
if(n == 0)
break;
for(int i = 0; i < n*(n - 1)/ 2; i ++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b] = map[b][a] = c;
}
printf("%d\n", prime());
}
}
N - 畅通工程再续
Description
Input
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
Output
Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
Sample Output
1414.2 oh!
被这题坑了超级久!!就是要注意10和1000 的判断的时候 是大于等于和小于等于! 还有我一开始连初始化都搞错了,结果还用VC 单步调试 T_T 、、、
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
#define N 220
#define Max 0x3fffffff
struct node
{
int x, y;
}po[N];
int vis[N];
double dis[N];
double map[N][N];
int n, ok;
double prime()
{
int i, j, k, t;
double ans = 0;
double min;
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
for(i = 1; i <= n; i ++)
{
dis[i] = map[1][i];
}
vis[1] = 1;
for(i = 1; i < n; i ++)
{
min = Max;
for(j = 1; j <= n; j ++)
{
if(!vis[j] && min - dis[j] > 0.00001)
{
min = dis[j];
t = j;
}
}
if(min == Max)
{
ok = 1;
return 0;
}
ans += min;
vis[t] = 1;
for(k = 1; k <= n; k ++)
{
if(!vis[k] && dis[k] - map [t][k] > 0.00001)
dis[k] = map[t][k];
}
}
return ans;
}
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t --)
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
{
scanf("%d%d",&po[i].x, &po[i].y);
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
if(i == j)
{
map[i][j] = 0;
continue;
}
double tmp1 = (po[i].x - po[j].x) * (po[i].x - po[j].x);
double tmp2 = (po[i].y - po[j].y) * (po[i].y - po[j].y);
double tmp3 = sqrt(tmp1 + tmp2);
//if(tmp3 - 10 > 0.00001 && 1000 - tmp3 > 0.00001)
if(tmp3 <= 1000 && tmp3 >= 10)
{
map[i][j] = map[j][i] = tmp3;
}
else
map[i][j] = map[j][i] = Max;
}
}
ok = 0;
double ttt = prime();
if(ok == 0)
{
printf("%.1f\n", ttt * 100);
}
else
printf("oh!\n");
}
}
}