『干货图论模板』

<更新提示>

<第一次更新>这是一篇记录图论模板的博客


<正文>

最短路篇

Dijkstra

#include<bits/stdc++.h>
using namespace std;
const int N=500000,M=1000000;
struct node
{
	int index,val;
	bool operator <(const node temp)const
	{
		return this->val<temp.val;
	}
	bool operator >(const node temp)const
	{
		return this->val>temp.val;
	}
};
struct edge
{
	int ver,val,next;
}e[M*2];
int n,m,dis[N],vis[N],Last[M*2],t,begin;
inline void insert(int x,int y,int v)
{
	e[++t].ver=y;e[t].val=v;e[t].next=Last[x];Last[x]=t;
}
inline void dijkstra(void)
{
	memset(vis,0x00,sizeof vis);
	memset(dis,0x3f,sizeof dis);
	priority_queue< node,vector< node >,greater< node > > Heap;
	Heap.push((node){begin,0});
	dis[begin]=0;
	while(!Heap.empty())
	{
		int temp=Heap.top().index;
		Heap.pop();
		if(vis[temp])continue;
		vis[temp]=true;
		for(int i=Last[temp];i;i=e[i].next)
		{
			int ver=e[i].ver;
			if(dis[ver]>dis[temp]+e[i].val)
			{
				dis[ver]=dis[temp]+e[i].val;
				Heap.push((node){ver,dis[ver]});
			}
		}
	}
}
int main(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,v;
		scanf("%d%d%d",&x,&y,&v);
		insert(x,y,v);
		insert(y,x,v);
	}
	scanf("%d",&begin);
	dijkstra();
	for(int i=1;i<=n;i++)
		printf("The distence from %d to %d is %d\n",begin,i,dis[i]);
	return 0;
}

SPFA

#include<bits/stdc++.h>
using namespace std;
const int N=500000,M=1000000;
struct edge
{
	int ver,val,next;
}e[M*2];
int n,m,dis[N],vis[N],Last[M*2],t,begin;
inline void insert(int x,int y,int v)
{
	e[++t].ver=y;e[t].val=v;e[t].next=Last[x];Last[x]=t;
}
inline void spfa(void)
{
	memset(vis,0x00,sizeof vis);
	memset(dis,0x3f,sizeof dis);
	queue < int > q;
	dis[begin]=0;vis[begin]=true;
	q.push(begin);
	while(!q.empty())
	{
		int temp=q.front();
		q.pop();
		vis[temp]=false;
		for(int i=Last[temp];i;i=e[i].next)
		{
			int ver=e[i].ver;
			if(dis[ver]>dis[temp]+e[i].val)
			{
				dis[ver]=dis[temp]+e[i].val;
				if(!vis[ver])
				{
					q.push(ver);
					vis[ver]=true;
				}
			}
		}
	}
}
int main(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,v;
		scanf("%d%d%d",&x,&y,&v);
		insert(x,y,v);
		insert(y,x,v);
	}
	scanf("%d",&begin);
	spfa();
	for(int i=1;i<=n;i++)
		printf("The distence from %d to %d is %d\n",begin,i,dis[i]);
	return 0;
}

最小生成树篇

Prim

#include<bits/stdc++.h>
using namespace std;
const int N=500000,M=1000000;
struct node
{
	int index,val;
	bool operator <(const node temp)const
	{
		return this->val<temp.val;
	}
	bool operator >(const node temp)const
	{
		return this->val>temp.val;
	}
};
struct edge
{
	int ver,val,next;
}e[M*2];
int n,m,dis[N],vis[N],Last[M*2],t,ans;
inline void insert(int x,int y,int v)
{
	e[++t].ver=y;e[t].val=v;e[t].next=Last[x];Last[x]=t;
}
inline void prim(void)
{
	memset(vis,0x00,sizeof vis);
	memset(dis,0x3f,sizeof dis);
	priority_queue< node,vector< node >,greater< node > > Heap;
	Heap.push((node){1,0});
	dis[1]=0;
	while(!Heap.empty())
	{
		node temp=Heap.top();
		Heap.pop();
		if(vis[temp.index])continue;
		vis[temp.index]=true;
		ans+=temp.val;
		int T=temp.index;
		for(int i=Last[T];i;i=e[i].next)
		{
			int ver=e[i].ver;
			if(dis[ver]>e[i].val)
			{
				dis[ver]=e[i].val;
				Heap.push((node){ver,dis[ver]});
			}
		}
	}
}
int main(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,v;
		scanf("%d%d%d",&x,&y,&v);
		insert(x,y,v);
		insert(y,x,v);
	}
	prim();
	printf("%d\n",ans);
	return 0;
}

Kruscal

#include<bits/stdc++.h>
using namespace std;
const int N=500000,M=1000000;
struct Link{int x,y,val;}e[M];
int n,m,ans,f[N];
inline bool cmp(Link p1,Link p2){return p1.val<p2.val;}
inline int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline void kruscal(void)
{
	int cnt=0;
	for(int i=1;i<=n;i++)
		f[i]=i;
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x==y)continue;
		f[x]=y;
		ans+=e[i].val;
		if(++cnt==n-1)break;
	}
}
int main(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
		scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].val);
	kruscal();
	printf("%d\n",ans);
	return 0;
}

树上问题篇

LCA

#include<cstdio>
#include<cstring>
#include<iostream>
#define mset(name,val) memset(name,val,sizeof name)
using namespace std;
const int N=30000+20,MaxlogN=30;
int n,Last[N],t,askx,asky,depth[N],f[N][MaxlogN],root=0,vis[N];
struct edge{int ver,next;}e[N];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		vis[y]=1;
	}
	scanf("%d%d",&askx,&asky);
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			root=i;
			break;
		}
	}
}
inline void init(int x,int dep)
{
	depth[x]=dep;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(f[x][0]==y)continue;
		f[y][0]=x;
		init(y,dep+1);
	}
}
inline void dp(void)
{
	f[root][0]=-1;
	for(int k=1;(1<<k)<n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			if(f[i][k-1]<0)f[i][k]=-1;
			else f[i][k]=f[f[i][k-1]][k-1];
		}
	}
}
inline int LCA(int x,int y)
{
	if(depth[x]>depth[y])x^=y^=x^=y;
	for(int d=depth[y]-depth[x],i=0;d;d>>=1,i++)
		if(d&1)y=f[y][i];
	if(x==y)return x;
	for(int i=MaxlogN-1;i>=0;i--)
	{
		if(f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
inline void reset(void)
{
	mset(Last,0);
	mset(e,0);
	mset(depth,0);
	mset(f,0);
	mset(vis,0);
	t=0;
} 
signed main(void)
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		reset();
		input();
		init(root,0);
		dp();
		printf("%d\n",LCA(askx,asky));
	}
	return 0;
}

树的直径BFS

#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#define mset(name,val) memset(name,val,sizeof name)
using namespace std;
const int N=40000+50;
int n,m,ans,vis[N],dis[N];
struct edge{int val,ver;};
vector < edge > Link[N];
inline void input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,v;
		scanf("%d%d%d",&x,&y,&v);
		Link[x].push_back((edge){v,y});
		Link[y].push_back((edge){v,x});
	}
}
inline int Search(int start)
{
	queue< int >q;
	mset(vis,0x00);
	mset(dis,0x00);
	vis[start]=1;
	q.push(start);
	while(!q.empty())
	{
		int temp=q.front();q.pop();
		for(int i=0;i<Link[temp].size();i++)
		{
			if(!vis[Link[temp][i].ver])
			{
				vis[Link[temp][i].ver]=true;
				dis[Link[temp][i].ver]=dis[temp]+Link[temp][i].val;
				q.push(Link[temp][i].ver);
			}
		}
	}
	int res=0,Maxdis=0;
	for(int i=1;i<=n;i++)
	{
		if(dis[i]>Maxdis)
		{
			Maxdis=dis[i];
			res=i;
		}
	}
	return res;
}
int main(void)
{
	input();
	int p=Search(1);
	printf("%d\n",dis[Search(p)]);
	return 0;
}

树的直径DP

#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#define mset(name,val) memset(name,val,sizeof name)
using namespace std;
const int N=40000+50;
int n,m,ans,vis[N],d[N],f[N];
struct edge{int val,ver;};
vector < edge > Link[N];
inline void input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,v;
		scanf("%d%d%d",&x,&y,&v);
		Link[x].push_back((edge){v,y});
		Link[y].push_back((edge){v,x});
	}
}
inline int dp(int x)
{
	vis[x]=true;
	for(int i=0;i<Link[x].size();i++)
	{
		int y=Link[x][i].ver;
		if(!vis[y])
		{
			dp(y);
			f[x]=max(f[x],d[x]+d[y]+Link[x][i].val);
			d[x]=max(d[x],d[y]+Link[x][i].val);
		}	
	}
	ans=max(ans,f[x]);
}
int main(void)
{
	input();
	dp(1);
	printf("%d\n",ans);
	return 0;
}

树的重心

#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#define mset(name,val) memset(name,val,sizeof name)
using namespace std;
const int N=20000+50;
int n,size[N],Max[N],ans,cnt;
vector < int > Link[N];
inline void input(void)
{
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		Link[x].push_back(y);
		Link[y].push_back(x);
	}
}
inline void dp(int r,int f)
{
	size[r]=1;
	for(int i=0;i<Link[r].size();i++)
	{
		int Son=Link[r][i];
		if(Son==f)continue;
		dp(Son,r);
		size[r]+=size[Son];
		Max[r]=max(Max[r],size[Son]);
	}
	Max[r]=max(Max[r],n-size[r]);
	if(Max[r]==Max[ans]&&r<ans)ans=r;
	if(Max[r]<Max[ans])ans=r;
}
int main(void)
{		
	Max[0]=0x3f3f3f3f;
	input();
	dp(1,0);
	printf("%d\n",ans);
}

树上差分(点)

#include<cstdio>
#include<cstring> 
#include<iostream>
using namespace std;
const int N=100000+200,K=200000+200,MaxlogN=30;
int n,k,cnt[N],depth[N],Last[N*2],t,f[N][MaxlogN],ans=0;
struct edge{int ver,next;}e[N*2];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
}
inline void init(int x,int dep)
{
	depth[x]=dep;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(f[x][0]==y)continue;
		f[y][0]=x;
		init(y,dep+1);
	}
}
inline void dp(void)
{
	f[1][0]=-1;
	for(int k=1;(1<<k)<n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			if(f[i][k-1]<0)f[i][k]=-1;
			else f[i][k]=f[f[i][k-1]][k-1];
		}
	}
}
inline int LCA(int x,int y)
{
	if(depth[x]>depth[y])
		x^=y^=x^=y;
	for(int d=depth[y]-depth[x],i=0;d;d>>=1,i++)
		if(1&d)y=f[y][i];
	if(x==y)return x;
	for(int i=MaxlogN-1;i>=0;i--)
	{
		if(f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
inline void Mark(void)
{
	for(int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		cnt[x]++;cnt[y]++;
		int lca=LCA(x,y);
		cnt[lca]--;
		if(lca!=1)cnt[f[lca][0]]--;
	}
}
inline void Get_sum(int r)
{
	for(int i=Last[r];i;i=e[i].next)
	{
		int Son=e[i].ver;
		if(Son==f[r][0])continue;
		Get_sum(Son);
		cnt[r]+=cnt[Son];
	}
	ans=max(ans,cnt[r]);
}
signed main(void)
{		
	input();
	init(1,0);
	dp();
	Mark();
	Get_sum(1);
	printf("%d\n",ans);
	return 0;
}

树上差分(边)

#include<cstdio>
#include<cstring> 
#include<iostream>
using namespace std;
const int N=100000+200,K=200000+200,MaxlogN=30;
int n,k,cnt[N],depth[N],Last[N*2],t,f[N][MaxlogN],ans=0;
struct edge{int ver,next;}e[N*2];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
}
inline void init(int x,int dep)
{
	depth[x]=dep;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(f[x][0]==y)continue;
		f[y][0]=x;
		init(y,dep+1);
	}
}
inline void dp(void)
{
	f[1][0]=-1;
	for(int k=1;(1<<k)<n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			if(f[i][k-1]<0)f[i][k]=-1;
			else f[i][k]=f[f[i][k-1]][k-1];
		}
	}
}
inline int LCA(int x,int y)
{
	if(depth[x]>depth[y])
		x^=y^=x^=y;
	for(int d=depth[y]-depth[x],i=0;d;d>>=1,i++)
		if(1&d)y=f[y][i];
	if(x==y)return x;
	for(int i=MaxlogN-1;i>=0;i--)
	{
		if(f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
inline void Mark(void)
{
	for(int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		cnt[x]++;cnt[y]++;
		int lca=LCA(x,y);
		cnt[lca]-=2;
	}
}
inline void Get_sum(int r)
{
	for(int i=Last[r];i;i=e[i].next)
	{
		int Son=e[i].ver;
		if(Son==f[r][0])continue;
		Get_sum(Son);
		cnt[r]+=cnt[Son];
	}
	ans=max(ans,cnt[r]);
}
signed main(void)
{		
	input();
	init(1,0);
	dp();
	Mark();
	Get_sum(1);
	printf("%d\n",ans);
	return 0;
}

图的连通性篇

Tarjan割点

#include<bits/stdc++.h>
using namespace std;
const int N=90000,M=150000;
int n,Last[M],t,cutvertex[N],dfn[N],low[N],cnt,m,ans[N],tot;
struct edge{int ver,next;}e[M];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		if(x^y)insert(x,y),insert(y,x);
	}
}
inline void Tarjan(int x,int root)
{
	dfn[x]=low[x]=++cnt;
	int flag=0;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			Tarjan(y,root);
			low[x]=min(low[x],low[y]);
			if(low[y]>=dfn[x])
			{
				flag++;
				if(x!=root||flag>1)cutvertex[x]=true;
			}
		}
		else low[x]=min(low[x],dfn[y]);
	}
}
int main(void)
{
	input();
	for(int i=1;i<=n;i++)
		if(!dfn[i])Tarjan(i,i);
	for(int i=1;i<=n;i++)
	{
		if(cutvertex[i])
			ans[++tot]=i;
	}
	if(tot)printf("%d\n",tot);
	else printf("0\n");
	for(int i=1;i<=tot;i++)
		printf("%d\n",ans[i]);		
}

Tarjan割边

#include<bits/stdc++.h>
using namespace std;
const int N=100000+200,M=300000+200;
int n,m,t=1,Last[M*2],dfn[N],low[N],bridge[N],cnt,tot;
struct edge{int ver,next;}e[M*2];
pair < int,int > ans[N];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
}
inline void Tarjan(int x,int inedge)
{
	dfn[x]=low[x]=++cnt;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			Tarjan(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x])
				bridge[i]=bridge[i^1]=true;
		}
		else if(i!=(inedge^1))
			low[x]=min(low[x],dfn[y]);
	}
}
int main(void)
{
	input();
	for(int i=1;i<=n;i++)
		if(!dfn[i])Tarjan(i,0);
	for(int i=2;i<t;i+=2)
		if(bridge[i])
		{
			if(e[i].ver>e[i^1].ver)swap(e[i].ver,e[i^1].ver);
			ans[++tot]=make_pair(e[i].ver,e[i^1].ver);
		}
	sort(ans+1,ans+tot+1);
	for(int i=1;i<=tot;i++)
		printf("%d %d\n",ans[i].first,ans[i].second);
	return 0;
}

Tarjan强连通分量

#include<bits/stdc++.h>
using namespace std;
const int N=20000+200,M=80000+200;
int n,m,dfn[N],low[N],cnt,Last[M*2],t,inSta[N],size[N],tot;
stack < int > Stack;
struct edge{int ver,next;}e[M*2];
struct connected
{
	int len=0;
	vector < int > List;
}con[N];
inline bool cmp(connected p1,connected p2)
{
	return p1.len>p2.len;
}
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int a,b,t;
		scanf("%d%d%d",&a,&b,&t);
		if(t==1)insert(a,b);
		else insert(a,b),insert(b,a);
	}
}
inline void Tarjan(int x)
{
	dfn[x]=low[x]=++cnt;
	Stack.push(x);inSta[x]=true;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			Tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(inSta[y])low[x]=min(low[x],dfn[y]);
	}
	if(low[x]==dfn[x])
	{
		int top=0;tot++;
		while(top!=x)
		{
			top=Stack.top();
			Stack.pop();
			con[tot].len++;
			con[tot].List.push_back(top);
			inSta[top]=false;
		}
	}
}
inline void print(void)
{
	sort(con[1].List.begin(),con[1].List.end());
	int T=1,best=1,l=con[1].len;
	for(int i=2;i<=tot;i++)
	{
		if(con[i].len==con[i-1].len)
		{
			sort(con[i].List.begin(),con[i].List.end());
			T++;
		}
		else break;
	}
	for(int i=2;i<=T;i++)
	{
		for(int j=0;j<l;j++)
		{
			if(con[i].List[j]<con[best].List[j])
			{
				best=i;
				break;
			}
			else if(con[i].List[j]>con[best].List[j])
				break;
		}
	}
	for(int i=0;i<l-1;i++)
		printf("%d ",con[best].List[i]);
	printf("%d\n",con[best].List[l-1]);
}
int main(void)
{
	input();
	for(int i=1;i<=n;i++)
		if(!dfn[i])Tarjan(i);
	sort(con+1,con+tot+1,cmp);
	printf("%d\n",con[1].len);
	print();
	return 0;
}

Tarjan点双连通分量

#include<bits/stdc++.h>
using namespace std;
const int M=500*3,N=1000;
int m,n,Last[N],t,dfn[N],low[N],cnt,T;
long long ans1,ans2=1;
struct edge{int ver,next;}e[M];
vector < int >con[N];
stack < int > Stack;
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline bool input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
	return true;
}
inline void Tarjan(int x,int root)
{
	dfn[x]=low[x]=++cnt;
	Stack.push(x);
	if(x==root&&!Last[x])
	{
		Stack.pop();T++;
		con[T].push_back(x);
		return;
	}
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			Tarjan(y,root);
			low[x]=min(low[x],low[y]);
			if(low[y]>=dfn[x])
			{
				int top=0;T++;
				while(top!=y)
				{
					top=Stack.top();
					Stack.pop();
					con[T].push_back(top);
				}
				con[T].push_back(x);
			}
		}
		else low[x]=min(low[x],dfn[y]);
	}
}
int main(void)
{
	input();
	Tarjan(1,1);
	for(int i=1;i<=T;i++)
	{
		printf("The vertex biconnected component #%d :",i);
		for(int j=0;j<con[i].size();j++)
			printf("%d ",con[i][j]);
		puts("");
	}
	return 0;
}

Tarjan边双连通分量

#include<bits/stdc++.h>
using namespace std;
const int N=10000,M=40000;
int n,m,Last[M],dfn[N],low[N],cnt,con[N],t=1,tot;
struct edge{int ver,next,flag;}e[M];
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
}
inline void Tarjan(int x,int inedge)
{
	dfn[x]=low[x]=++cnt;
	for(int i=Last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			Tarjan(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x])e[i].flag=e[i^1].flag=true;
		}
		else if(i!=(inedge^1))low[x]=min(low[x],dfn[y]);
	}
}
inline void dfs(int x)
{
	con[x]=tot;
	printf("%d ",x);
	for(int i=Last[x];i;i=e[i].next)
	{
		if(e[i].flag)continue;
		int y=e[i].ver;
		if(!con[y])dfs(y);
	}
}
inline void colored(void)
{
	for(int i=1;i<=n;i++)
		if(!con[i])
		{
			++tot;
			printf("The Edge biconnected component #%d :",tot);
			dfs(i);
			puts("");
		}
}
int main()
{
	input();
	Tarjan(1,0);
	colored(); 
	return 0;
}

判环篇

Topsort

#include<bits/stdc++.h>
using namespace std;
const int N=500000,M=1000000;
struct edge
{
	int ver,next;
}e[M*2];
int n,m,Last[M*2],t,loop,indeg[N],cnt,ans[N];
queue < int > q;
inline void insert(int x,int y)
{
	e[++t].ver=y;e[t].next=Last[x];Last[x]=t;
}
inline bool topsort(void)
{
	for(int i=1;i<=n;i++)
		if(!indeg[i])q.push(i);
	while(!q.empty())
	{
		int temp=q.front();q.pop();ans[++cnt]=temp;
		for(int i=Last[temp];i;i=e[i].next)
		{
			int ver=e[i].ver;
			indeg[ver]--;
			if(!indeg[ver])q.push(ver);
		}
	}
	return cnt==n;
}
int main(void)
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		indeg[y]++;
	}
	topsort();
	if(loop)printf("Impossible\n");
	else
		for(int i=1;i<=n;i++)
			printf("%d ",ans[i]);
	puts("");
	return 0;
}

<后记>

posted @ 2019-02-18 20:20  Parsnip  阅读(193)  评论(0编辑  收藏  举报