您的位置:首页 > 理论基础 > 计算机网络

F. Islands 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛

2017-09-09 19:09 363 查看
题目还不能看,先贴代码过来

基本就是先强连通分量缩点,

然后统计一下出度入度为零的点

code

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<vector>
#define N 10005
using namespace std;
struct Edge
{
int dest;
Edge *next;
}*GA
,*GT
,*G
;
int used
,path
,part
,m,n;
bool mark

;
int in
,out
;
void addedge(Edge *T[],int i,int j)
{
Edge *L;
L=new Edge;
L->dest=j;
L->next=T[i];
T[i]=L;
}
void DFSA(int s)
{
Edge *l;
if(!used[s])
{
used[s]=1;
for(l=GA[s];l!=NULL;l=l->next)
DFSA(l->dest);
path[0]++;
path[path[0]]=s;
}
}
void DFST(int s)
{
Edge *l;
if(! used[s])
{
used[s]=1;
for(l=GT[s];l!=NULL;l=l->next)
DFST(l->dest);
part[s]=part[0];
}
}
void Kosaraju()
{
int i,j,k;
Edge *L;
memset(used ,0,sizeof(used));
path[0]=part[0]=0;
for(i=1;i<=n;i++)
DFSA(i);
memset(used,0,sizeof(used));
for(i=n;i>=1;i--)
{
if(!used[path[i]])
{
part[0]++;
DFST(path[i]);
}
}
memset(mark,0,sizeof(mark));
for(k=1;k<=n;k++)
{
for(L=GA[k],i=part[k];L!=NULL;L=L->next)
{
j=part[L->dest];
if(i!=j&&!mark[i][j])
{
mark[i][j]=1;
addedge(G,i,j);
}
}
}
}
int main()
{
int i,a,b;
Edge *L;
int t,mm;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&mm);
for(i=1;i<=n;i++)
GA[i]=GT[i]=G[i]=NULL;

while(mm--)
{
scanf("%d%d",&a,&b);
addedge(GA,a,b);
addedge(GT,b,a);
}
if(n==1){printf("0\n");continue;}
Kosaraju();
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(m=part[0],i=1;i<=m;i++)
{
for(L=G[i];L!=NULL;L=L->next)
{
out[i]++;
in[L->dest]++;
}
}

for(a=b=0,i=1;i<=m;i++)
{
if(!in[i]) a++;
if(!out[i]) b++;
}
b=a>b?a:b;
if(m==1) printf("0\n");
else printf("%d\n",b);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐