http://acm.hdu.edu.cn/showproblem.php?pid=3357
按所给的顺序,给出一条有向边,如果加上这条边会出现环,那就舍弃这条边,问一共有几条边要舍弃
如果加入的边a到b不会出现环,要做一次更新,有三类更新:
i->a->b->j => i->j;
i->a->b => i->b;
a->b->j => a->j
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int map[500][500];
int n,t;
void update(int a,int b)
{
int i;
map[a][b]=1;
for(i=1;i<=n;i++)
{
if(map[i][a])
map[i][b]=1;
}
for(i=1;i<=n;i++)
{
if(map[b][i])
{
//map[a][i]=1;
int j;
for(j=1;j<=n;j++)
{
if(map[j][b])
map[j][i]=1;
}
}
}
}
int main()
{
int cas=1;
while(scanf("%d%d",&n,&t))
{
if(n==0&&t==0)
break;
memset(map,0,sizeof(map));
int i;
int res=0;
for(i=0;i<t;i++)
{
int t1,t2;
scanf("%d%d",&t1,&t2);
if(map[t1][t2])
continue;
if(map[t2][t1])
{
res++;
continue;
}
if(t1==t2)
{
res++;
continue;
}
update(t1,t2);
}
printf("%d. %d\n",cas++,res);
}
return 0;
}