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
栅栏循环
围绕着农民布朗的牧场的栅栏已经失控了。它们由从1到200英尺长的直段组成,它们只连接在它们的端点上,尽管有时在给定的端点上有超过两个栅栏连接在一起。结果就是他的牧场上围了一圈篱笆。农场主布朗想要把事情弄清楚。特别地,他想知道哪个牧场的周长最小。
农场主布朗把他的篱笆段数从1到N (N=总数的总数)。他对每一个栅栏都有以下的了解:
线段的长度
一端连接到一端的段
在另一端连接到它的段。
幸运的是,没有围栏连接到自己。
给定一组栅栏,代表一组被包围的牧场,编写一个程序来计算任何牧场的最小周长。作为一个例子,考虑一个牧场的安排,篱笆的编号是1到10,看起来就像这个(数字是篱笆的编号):
1 +---------------+ |\ /| 2| \7 / | | \ / | +---+ / |6 | 8 \ /10 | 3| \9 / | | \ / | +-------+-------+ 4 5
最小周长的牧场是由栅栏围起来的2、7和8围起来的。
项目名称:fence6
输入格式
第一行:N(1小于=N小于=100)
2 . . 3 * N + 1行:
每组三行:
每个记录的第一行包含四个整数:s、段号(1<=s<=N);Ls,线段的长度(1<=Ls<=255);N1s(1<=N1s<=8)一端的栅栏数;然后在后面表示的是另一端的栅栏数(1<=N2s<=8)。
数字的第二行包含N1整数,每一个都表示一个连接在栅栏一端的连接的线段。
数字的第三行包含N2个整数,每个代表一个连接在另一端的连接的线段。
示例输入(文件fence6.in)
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
五
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
输出格式
输出文件应该包含一个单一的行,其中包含一个表示最短的周长的整数。
样例输出(文件fence6.out)
12
/*
ID : mcdonne1
LANG : C++
TASK : fence6
*/
#include<cstdio>
#include<map>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,s,l,n1,n2,cnt,ans=0x7fffffff;
int e[10],hash[10]={1};
int f[101][101],g[101][101];
map <long long,int> m;
int main()
{
freopen("fence6.in","r",stdin);
freopen("fence6.out","w",stdout);
for(int i=1;i<=8;++i) hash[i]=hash[i-1]*100;
scanf("%d",&n);
memset(f,31,sizeof(f));
memset(g,31,sizeof(g));
for(int i=1;i<=n;++i)
{
scanf("%d%d%d%d",&s,&l,&n1,&n2);
long long __h1=0,__h2=0;
e[0]=s;
for(int i=1;i<=n1;++i) scanf("%d",&e[i]);
sort(e,e+1+n1);
for(int i=0;i<=n1;++i) __h1+=e[i]*hash[i];
e[0]=s;
for(int i=1;i<=n2;++i) scanf("%d",&e[i]);
sort(e,e+1+n2);
for(int i=0;i<=n2;++i) __h2+=e[i]*hash[i];
if(m[__h1]==0) m[__h1]=++cnt;
if(m[__h2]==0) m[__h2]=++cnt;
f[m[__h1]][m[__h2]]=f[m[__h2]][m[__h1]]=g[m[__h1]][m[__h2]]=g[m[__h2]][m[__h1]]=l;
}
for(int k=1;k<=cnt;++k)
{
for(int i=1;i<=cnt;++i)
for(int j=1;j<=cnt;++j)
if(i!=j&&j!=k&&k!=i)
ans=min(ans,f[i][j]+g[i][k]+g[k][j]);
for(int i=1;i<=cnt;++i)
for(int j=1;j<=cnt;++j)
if(i!=j&&j!=k&&k!=i)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
printf("%d\n",ans);
return 0;
}