BZOJ2278: [Poi2011]Garbage

来源:互联网 发布:云计算的发展现状 编辑:程序博客网 时间:2024/06/18 05:15
题目大意:给定n个点m条边,每条边有一个初始权值0或1,有一个最终权值0或1,每次可以给一个简单环上的边权值异或1,求一种方案使得每条边从初始权值变成最终权值

一看这个样子就知道不需要该变的边没啥用,因为反正都要变两次,不如把这两次合起来,然后这些边不变..
然后我就写了一个找欧拉回路的算法,交上去WA了....


然后就要了数据,发现需要特判单独的点,否则会输出一些奇怪的东西....
然后还是WA
TAT||||

为啥题里没说“必须是简单环”啊,这样欧拉回路就不行了....那我们可以维护一个像栈一样的东西遇到一个环就弹出去
再交一发TLE...

然后就想起来毛啸出的那道coloring....也就是邻接表求欧拉回路的时间复杂度会退化到O(N^2)
所以就要用到类似网络流的当前弧优化的东西

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define N 1000010using namespace std;int to[N<<1],nxt[N<<1],num[N<<1],pre[N],cnt;void NO(){puts("NIE");exit(0);}void ae(int ff,int tt){cnt++;to[cnt]=tt;nxt[cnt]=pre[ff];pre[ff]=cnt;num[cnt]=(cnt-1)/2;}int du[N];bool used[N],vis[N];int fark;void dfs(int x){fark++;used[x]=true;int i,j;for(i=pre[x];i;i=nxt[i]){j=to[i];if(used[j]) continue;dfs(j);}}vector<int>V[N];int tot;bool zai[N];int s[N],t;void dfs2(int x){used[x]=true;if(zai[x]){tot++;V[tot].push_back(x);while(s[t]!=x){zai[s[t]]=false;V[tot].push_back(s[t]);t--;}zai[s[t]]=false;V[tot].push_back(s[t]);t--;}int i,j;for(i=pre[x];i;i=pre[x]){pre[x]=nxt[i];if(!vis[num[i]]){zai[x]=true;t++;s[t]=x;vis[num[i]]=true;dfs2(to[i]);}}}char ch,B[1<<15],*S=B,*T=B;#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)inline int read(){    int x=0,f=1;char ch=getc();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}    return x*f;}int main(){int n,m;n=read();m=read();int i,j,x,y,u,v;while(m--){x=read();y=read();u=read();v=read();if(u!=v){du[x]++;du[y]++;ae(x,y),ae(y,x);}}for(i=1;i<=n;i++)if(du[i]&1) NO();for(i=1;i<=n;i++)if(!used[i])dfs2(i);printf("%d\n",tot);for(i=1;i<=tot;i++){printf("%d ",V[i].size()-1);for(j=0;j<V[i].size();j++)printf("%d ",V[i][j]);puts("");}}

0 0
原创粉丝点击