usaco 4.3 Street Race 2010.8.7

Street Race

IOI'95 Figure 1 gives an example of acourse for a street race. You see some points, labeled from 0 to N (here, N=9),and some arrows connecting them. Point 0 is the start of the race; point N isthe finish. The arrows represent one-way streets. The participants of the racemove from point to point via the streets, in the direction of the arrows only.At each point, a participant may choose any outgoing arrow.

 

 

Figure 1: A street course with 10 points Awell-formed course has the following properties:

 

Every point in the course can be reachedfrom the start.

The finish can be reached from each pointin the course.

The finish has no outgoing arrows.

A participant does not have to visit everypoint of the course to reach the finish. Some points, however, are unavoidable.In the example, these are points 0, 3, 6, and 9. Given a well-formed course,your program must determine the set of unavoidable points that all participantshave to visit, excluding start and finish.

 

Suppose the race has to be held on twoconsecutive days. For that purpose the course has to be split into two courses,one for each day. On the first day, the start is at point 0 and the finish atsome `splitting point'. On the second day, the start is at this splitting pointand the finish is at point N. Given a well-formed course, your program mustalso determine the set of splitting points. A point S is a splitting point forthe well-formed course C if S differs from the star t and the finish of C, andthe course can be split into two well-formed courses that (1) have no commonarrows and (2) have S as their only common point, with S appearing as thefinish of one and the start of the other. In the example, only point 3 is asplitting point.

 

PROGRAM NAME: race3

INPUT FORMAT

The input file contains a well-formedcourse with at most 50 points and at most 100 arrows. There are N+2 lines inthe file. The first N+1 lines contain the endpoints of the arrows that leavefrom the points 0 through N respectively. Each of these lines ends with thenumber -2. The last line contains only the number -1.

 

SAMPLE INPUT (file race3.in)

1 2 -2

3 -2

3 -2

5 4 -2

6 4 -2

6 -2

7 8 -2

9 -2

5 9 -2

-2

-1

OUTPUT FORMAT

Your program should write two lines. Thefirst line should contain the number of unavoidable points in the input course,followed by the labels of these points, in ascending order. The second lineshould contain the number of splitting points of the input course, followed bythe labels of all these points, in ascending order.

 

SAMPLE OUTPUT (file race3.out)

2 3 6

1 3

Compiling...

Compile: OK

 

Executing...

  Test 1: TEST OK [0.000 secs, 2892 KB]

  Test 2: TEST OK [0.011 secs, 2892 KB]

  Test 3: TEST OK [0.000 secs, 2892 KB]

  Test 4: TEST OK [0.011 secs, 2892 KB]

  Test 5: TEST OK [0.000 secs, 2892 KB]

  Test 6: TEST OK [0.000 secs, 2892 KB]

  Test 7: TEST OK [0.011 secs, 2892 KB]

   Test 8: TEST OK [0.011 secs, 2892 KB]

  Test 9: TEST OK [0.011 secs, 2892 KB]

  Test 10: TEST OK [0.011 secs, 2892 KB]

  Test 11: TEST OK [0.011 secs, 2892 KB]

 

All tests OK.

 

Your program ('race3') produced all correctanswers! This is your

submission #3 for this problem.Congratulations!


#include <cstdio>
#include <cstring>

using namespace std;

#define MAXN 55

int a[MAXN],b[MAXN],la=0,lb=0;
int n=-1;
bool f[MAXN][MAXN],g[MAXN][MAXN];
bool v[MAXN];
int i=0,flag,k;

void search(int vtx)//搜索没有k点时,其他点的到达情况
{
v[vtx]=true;
for(int i=0;i<=n;i++)
   if (i!=k && f[vtx][i] && !v[i]) search(i);
}

void init()
{
freopen("race3.in","r",stdin);
freopen("race3.out","w",stdout);
memset(f,0,sizeof(f));
while(i!=-1)
   for(++n;;)
   {
    scanf("%d",&i);
    if (i<0) break;
    f[n][i]=true;
   }
n--;

}

void floyd()
{
int i,j,k;
memcpy(g,f,sizeof(f));
for(k=0;k<=n;k++)
   for(i=0;i<=n;i++)
    for(j=0;j<=n;j++)
     if (g[i][k]&&g[k][j]) g[i][j]=true;
}

void doit()
{
for(k=1;k<n;k++)
{
   memset(v,0,sizeof(v));
   search(0);//不要k点的时候
   if (!v[n])//终点不能到达
   {
    la++;
    a[la]=k;//第一问
    for(flag=1,i=0;i<n;i++)
     if (v[i]&&g[k][i])//不要k点时,i点可以到达,而且 k->i 可达 ,说明其它点可到达i,这样就不满足第二问了
     {
      flag=0;
      break;
     }
    if (flag) 
    {
     lb++;
     b[lb]=k;
    }
   }
}
}

void outit()
{
printf("%d",la);
for(int i=1;i<=la;i++)
   printf(" %d",a[i]);
printf("\n");
printf("%d",lb);
for(int i=1;i<=lb;i++)
   printf(" %d",b[i]);
printf("\n");
}


int main()
{
init();
floyd();
doit();
outit();
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值