【JZOJ6409】困難的圖論

description

給定由 n 個點 m 條邊組成的無向連通圖,保證沒有重邊和自環。
你需要找出所有邊,滿足這些邊恰好存在於一個簡單環中。一個環被稱爲簡單環,當且僅當它包含的所有點都只在這個環中被經過了一次。
注意到這些邊可能有很多條,你只需要輸出他們編號的異或和即可。


analysis

  • 然而複習了一波tarjantarjan,其實這個簡單環就是求點雙

  • 求出每個點雙,判斷點雙裏的邊數是否等於點雙點數

  • 這個不能暴力求,方法就是記錄每個點有多少條返祖邊、返祖邊的異或和

  • 因爲這些返祖邊指向的點和該點本身肯定在同一個點雙中

  • 感覺tarjantarjan這種東西還是記下好一點,不過跑得好慢很奇怪


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define MAXN 1000005
#define MAXM 2000005
#define ll int
#define reg register ll
#define max(x,y) ((x>y)?(x):(y))
#define min(x,y) ((x<y)?(x):(y))
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i])

using namespace std;

ll last[MAXM],next[MAXM],tov[MAXM],id[MAXM];
ll dfn[MAXN],low[MAXN],stack[MAXN],where[MAXN],num[MAXN],xorval[MAXN];
ll n,m,tot,top,ans,sum,root=1,size;
bool bz[MAXN],cut[MAXN];
vector<ll>v[MAXN];

inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline void link(ll x,ll y,ll z){next[++tot]=last[x],last[x]=tot,tov[tot]=y,id[tot]=z;}
inline void tarjan(ll x)
{
	dfn[x]=low[x]=++tot,bz[x]=1,stack[++top]=x;ll flag=0;
	rep(i,x)if (!dfn[tov[i]])
	{
		tarjan(tov[i]),low[x]=min(low[x],low[tov[i]]);
		if (low[tov[i]]>=dfn[x])
		{
			++flag,++sum;ll tmp,total=0,xorsum=0;
			if (x!=root || flag>1)cut[x]=1;
			do
			{
				tmp=stack[top--],v[sum].push_back(tmp),total+=num[tmp],xorsum^=xorval[tmp];
			}
			while (tmp!=tov[i]);
			v[sum].push_back(x);
			if (total==v[sum].size())ans^=xorsum;
		}
	}
	else
	{
		if (dfn[tov[i]]>dfn[x])continue;
		++num[x],xorval[x]^=id[i];
		low[x]=min(low[x],dfn[tov[i]]);
	}
}
int main()
{
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	n=read(),m=read();
	fo(i,1,m)
	{
		ll x=read(),y=read();
		link(x,y,i),link(y,x,i);
	}
	tot=0,tarjan(1);
	printf("%d\n",ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章