现在的位置: 首页 > 综合 > 正文

ZOJ3378

2019年08月21日 ⁄ 综合 ⁄ 共 1419字 ⁄ 字号 评论关闭

挫爆了跑了快4s

做法比较挫,先dfs到终点,即找一个路径,标记下,(割边只可能是路径上的),然后tarjan下即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#define MAXN 10003
#define MAXM 200033
using namespace std;
int n,m,dfn[MAXN],low[MAXN],head[MAXN],cnt,v[MAXN],ans[MAXN],tot,sum;
struct EDGE
{
	int to,nxt,tag,cur,db;
}edge[MAXM];
void init()
{
	cnt=tot=sum=0;
	memset(head,-1,sizeof(head));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(v,0,sizeof(v));
}
void add(int x,int y,int i)
{
	int j;
	for(j=head[x];j!=-1;j=edge[j].nxt)
	{
		if(edge[j].to==y)
			break;
	}
	if(j!=-1)
	{
		edge[j].db=1;
		return;
	}
	edge[cnt].to=y;
	edge[cnt].nxt=head[x];
	edge[cnt].tag=0;
	edge[cnt].cur=i;
	edge[cnt].db=0;
	head[x]=cnt++;
}
void addedge(int x,int y,int i)
{
	add(x,y,i);
	add(y,x,i);
}
int dfs(int x)
{
	v[x]=1;
	if(x==n-1)
		return 1;
	for(int j=head[x];j!=-1;j=edge[j].nxt)
	{
		int y=edge[j].to;
		if(v[y])
			continue;
		edge[j].tag=1;
		edge[j^1].tag=1;
		v[y]=1;
		if(dfs(y))return 1;
		edge[j].tag=0;
		edge[j^1].tag=0;
	}
	return 0;
}
void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++tot;
	for(int j=head[x];j!=-1;j=edge[j].nxt)
	{
		int y=edge[j].to;
		if(!dfn[y])
		{
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
			if(edge[j].tag&&low[y]>dfn[x]&&!edge[j].db)
				ans[sum++]=edge[j].cur;
		}
		else
			if(y!=fa)
				low[x]=min(low[x],dfn[y]);
	}
}
int main()
{
	while(2==scanf("%d%d",&n,&m))
	{
		int a,b;
		init();
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			addedge(a,b,i);
		}
		dfs(0);
		tarjan(0,-1);
		sort(ans,ans+sum);
		printf("%d\n",sum);
		
			for(int i=0;i<sum;i++)
			{
				if(i==0)
				printf("%d",ans[i]);
				else
				printf(" %d",ans[i]);
			}
			puts("");	
	}
	return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.