题意:
给出一个n个点m条边无向图,每个边有一个01状态;
现在可以选择一些环,使环上的所有状态取反;
给出初始与结束状态,求一个方案;
1<=n<=100000,1<=m<=1000000;
题解:
做完这题深刻的体会到自己的too young too naive;
首先有一个性质,如果有解,一定存在一种方案使选择的所有环不重复经过一条边;
这个性质也说明了,所有不需要更改的边是可以忽视的;
因为如果将其选了偶数次,也可以构造出另一种方案不选它;
所以问题转化成从原图选出状态不同的边,然后求多个欧拉回路覆盖所有边的方案;
无向图存在欧拉回路的条件是结点的度都是偶数;
判掉NIE的情况之后,开始求图的欧拉回路。。
然后我写个搜索就被卡了!并不是常数的问题而是复杂度不对;
首先大多数人的图都是用链式前向星存对吧;
那么每次搜到一个点遍历一遍边表找没被删除的边的时候。。
这就给了丧心病狂的人可乘之机!
给出一个是:
这个样子的菊花图,5W个褶,然后扫着扫着就超时了;
所以我们要更新前向星中的head[x],每次删除的边都是最上面的,只要将head[x]赋为某个next就行了;
时间复杂度O(n+m),读入较大,输出较大,常数较大;
在连续几道题垫底的节奏下终于有一道题Rank1啦好开心;
代码:
#include<cctype> #include<vector> #include<stdio.h> #include<string.h> #include<algorithm> #define N 131072 #define M 2100000 #define LEN 1<<20 using namespace std; int to[M],next[M],head[N],ce=1; int du[N]; bool ban[M],vis[N]; int cnt; char getc() { static char *S,*T,buf[LEN]; if(S==T) { T=(S=buf)+fread(buf,1,LEN,stdin); if(S==T) return EOF; } return *S++; } int read() { static char ch; static int D; while(!isdigit(ch=getc())); for(D=ch-'0';isdigit(ch=getc());) D=D*10+ch-'0'; return D; } namespace ans { int val[M],next[M],head[N<<1],size[N<<1],ce; void add(int x,int y) { size[x]++; val[++ce]=y; next[ce]=head[x]; head[x]=ce; } } void add(int x,int y) { to[++ce]=y; next[ce]=head[x]; head[x]=ce; } int dfs(int x,int pre) { vis[x]=1; int i,y; for(i=head[x];i;i=next[i]) { if(ban[i]||(i^1)==pre) continue; if(!vis[to[i]]) { y=dfs(to[i],i); ans::add(cnt,x); ban[i]=ban[i^1]=1; head[x]=next[i]; if(x!=y) { vis[x]=0; return y; } } else { cnt++; ans::add(cnt,to[i]); ans::add(cnt,x); ban[i]=ban[i^1]=1; head[x]=next[i]; vis[x]=0; return to[i]; } } vis[x]=0; return 0; } int main() { int n,m,i,j,k,x,y,z,w; n=read(),m=read(); for(i=1;i<=m;i++) { x=read(),y=read(),z=read(),w=read(); if(z!=w) add(x,y),add(y,x),du[x]++,du[y]++; } for(i=1;i<=n;i++) { if(du[i]&1) { puts("NIE"); return 0; } } for(i=1;i<=n;i++) { if(head[i]) dfs(i,0); } printf("%d\n",cnt); for(i=1;i<=cnt;i++) { printf("%d ",ans::size[i]-1); for(j=ans::head[i];j;j=ans::next[j]) { printf("%d ",ans::val[j]); } printf("\n"); } return 0; }
原文地址:http://blog.csdn.net/ww140142/article/details/48676373