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
/*
ID: conicoc1
LANG: C
TASK: fence6
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Min(a,b) a>b?b:a
int E[101][2][9];
int Length[101];
int flag[101];
int N;
int MinLen=25500,NowLen;
//判断线段0的一边是否连接直线n
int JudgeAlong(int edge1,int side,int edge2)
{
int i;
for(i=1;i<=E[edge1][side][0];i++)
if(E[edge1][side][i]==edge2)
return 1;
return 0;
}
void DFS(int Sedge,int Sside,int edge,int side)
{
if(JudgeAlong(Sedge,1-Sside,edge)){
MinLen=Min(MinLen,NowLen);
return;
}
int i,NextSide=0;
for(i=1;i<=E[edge][side][i];i++){
if(flag[E[edge][side][i]])
continue;
NowLen+=Length[E[edge][side][i]];
if(JudgeAlong(E[edge][side][i],NextSide,edge))
NextSide=1-NextSide;
flag[E[edge][side][i]]=1;
DFS(Sedge,Sside,E[edge][side][i],NextSide);
NowLen-=Length[E[edge][side][i]];
flag[E[edge][side][i]]=0;
}
}
int main()
{
FILE *fin,*fout;
fin=fopen("fence6.in","r");
fout=fopen("fence6.out","w");
fscanf(fin,"%d",&N);
int i,j,Number,Line1,Line2;
for(i=0;i<N;i++){
fscanf(fin,"%d",&Number);
fscanf(fin,"%d %d %d",&Length[Number],&E[Number][0][0],&E[Number][1][0]);
for(j=1;j<=E[Number][0][0];j++)
fscanf(fin,"%d",&E[Number][0][j]);
for(j=1;j<=E[Number][1][0];j++)
fscanf(fin,"%d",&E[Number][1][j]);
}
for(i=1;i<N;i++){
NowLen=Length[i];
DFS(i,0,i,0);
flag[i]=1;
}
fprintf(fout,"%d\n",MinLen);
return 0;
}
在无向图中找到周长最小的圈。
这道题我存了边,省的转化成点了
对每条边进行DFS找到所有可行的圈,判断周长,DFS结束后标记已经访问。
注意DFS过程中对边的搜索方向问题。