The fences that surround Farmer Brown's collection of pastures have gotten out of control. They are made up of straight segments from 1 through 200 feet long that join together only at their endpoints though sometimes more than two fences join together at a given endpoint. The result is a web of fences enclosing his pastures. Farmer Brown wants to start to straighten things out. In particular, he wants to know which of the pastures has the smallest perimeter.
Farmer Brown has numbered his fence segments from 1 to N (N = the total number of segments). He knows the following about each fence segment:
- the length of the segment
- the segments which connect to it at one end
- the segments which connect to it at the other end.
Given a list of fence segments that represents a set of surrounded pastures, write a program to compute the smallest perimeter of any pasture. As an example, consider a pasture arrangement, with fences numbered 1 to 10 that looks like this one (the numbers are fence ID numbers):
1 +---------------+ |\ /| 2| \7 / | | \ / | +---+ / |6 | 8 \ /10 | 3| \9 / | | \ / | +-------+-------+ 4 5
The pasture with the smallest perimeter is the one that is enclosed by fence segments 2, 7, and 8.
PROGRAM NAME: fence6
INPUT FORMAT
Line 1: | N (1 <= N <= 100) |
Line 2..3*N+1: | N sets of three line records:
|
SAMPLE INPUT (file fence6.in)
10 1 16 2 2 2 7 10 6 2 3 2 2 1 7 8 3 3 3 2 1 8 2 4 4 8 1 3 3 9 10 5 5 8 3 1 9 10 4 6 6 6 1 2 5 1 10 7 5 2 2 1 2 8 9 8 4 2 2 2 3 7 9 9 5 2 3 7 8 4 5 10 10 10 2 3 1 6 4 9 5
OUTPUT FORMAT
The output file should contain a single line with a single integer that represents the shortest surrounded perimeter.SAMPLE OUTPUT (file fence6.out)
12
题意:
给定边,以及边相邻的边,求最小环
(显然,转点很恶心)
参考了网上一些方法,具体的有:
folyd最小环
dijkstra先删边再加边处理
DFS判环
边化点处理
……
感觉边化点可能好编,但是不会,最容易的应该是DFS,因为读入的是边之间的关系.
/* ID:cqz15311 LANG:C++ PROG:fence6 */ #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> int start,ans,n,c; int f[305],num[305][2],map[305][2][305]; bool vis[305]; int find(int a,int b){ for (int i=1;i<=num[b][0];i++) if (map[b][0][i]==a) return 0; return 1; } void dfs(int u,int d,int s){ if (s > ans) return; if (u == start && s > 0){ ans = s; return ; } vis[u] = true; for (int i=1;i<=num[u][d];i++){ //之前从左边过来的,现在要往右边去 //否则,从右边要到左边 int v = map[u][d][i]; if (!vis[v] || (v == start)) dfs(v,find(u,v) ^ 1,s + f[u]); //方向是不确定的…… } vis[u] = false; } int main(){ freopen("fence6.in","r",stdin); freopen("fence6.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%d",&c); scanf("%d%d%d",&f[c],&num[c][0],&num[c][1]); for (int j=1;j<=num[c][0];j++) scanf("%d",&map[c][0][j]); for (int j=1;j<=num[c][1];j++) scanf("%d",&map[c][1][j]); //读入边 } ans = 0x3fffffff; for (start = 1; start <= n;start ++){ memset(vis,false,sizeof(vis)); dfs(start,0,0); } printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0; } /* Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 4908 KB] Test 2: TEST OK [0.000 secs, 4908 KB] Test 3: TEST OK [0.000 secs, 4908 KB] Test 4: TEST OK [0.000 secs, 4908 KB] Test 5: TEST OK [0.000 secs, 4908 KB] Test 6: TEST OK [0.000 secs, 4908 KB] Test 7: TEST OK [0.000 secs, 4908 KB] Test 8: TEST OK [0.000 secs, 4908 KB] Test 9: TEST OK [0.000 secs, 4908 KB] All tests OK. YOUR PROGRAM ('fence6') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations. 其它方法可参考 http://train.usaco.org/usacoanal2?a=i62AGyUxgsm&S=fence6 */