【POJ】【1637】Sightseeing tour
网络流/最大流
愚人节快乐XD
这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路……
我们知道如果一个【连通】图中每个节点都满足【入度=出度】那么就一定有欧拉回路……
那么每条边都可以贡献一个出度出来,对于一条边u->v:
连S->edge cap=1;
如果是有向边,就连 edge->v cap=1;
否则(无向边)连edge->u cap=1, edge->v cap=1;
然后每个点的总度数我们是知道的……那么它最后的【出度】就等于 总度数/2。(这个地方我傻逼了没想到……
P.S.这题是跟POJ2699比较类似的
1 Source Code 2 Problem: 1637 User: sdfzyhy 3 Memory: 1148K Time: 32MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //BZOJ 1000 9 #include<vector> 10 #include<cstdio> 11 #include<cstdlib> 12 #include<cstring> 13 #include<iostream> 14 #include<algorithm> 15 #define rep(i,n) for(int i=0;i<n;++i) 16 #define F(i,j,n) for(int i=j;i<=n;++i) 17 #define D(i,j,n) for(int i=j;i>=n;--i) 18 using namespace std; 19 20 int getint(){ 21 int v=0,sign=1; char ch=getchar(); 22 while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();} 23 while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();} 24 return v*sign; 25 } 26 typedef long long LL; 27 const int N=100010,M=100010,INF=~0u>>2; 28 /*******************tamplate********************/ 29 int n,m,ans,du[1000]; 30 struct edge{int to,v;}; 31 struct Net{ 32 edge E[M]; 33 int next[M],head[N],cnt; 34 void ins(int x,int y,int z){E[++cnt]=(edge){y,z};next[cnt]=head[x];head[x]=cnt;} 35 void add(int x,int y,int z){ins(x,y,z); ins(y,x,0);} 36 int S,T,d[N],Q[M],cur[N]; 37 bool mklevel(){ 38 F(i,0,T) d[i]=-1; 39 int l=0,r=-1; 40 Q[++r]=S; d[S]=0; 41 while(l<=r){ 42 int x=Q[l++]; 43 for(int i=head[x];i;i=next[i]) 44 if(E[i].v && d[E[i].to]==-1){ 45 d[E[i].to]=d[x]+1; 46 Q[++r]=E[i].to; 47 } 48 } 49 return d[T]!=-1; 50 } 51 int dfs(int x,int a){ 52 if(x==T)return a; 53 int flow=0; 54 for(int &i=cur[x];i && flow<a;i=next[i]) 55 if(E[i].v && d[E[i].to]==d[x]+1){ 56 int f=dfs(E[i].to,min(a-flow,E[i].v)); 57 E[i].v-=f; 58 E[i^1].v+=f; 59 flow+=f; 60 } 61 if(!flow) d[x]=-1; 62 return flow; 63 } 64 void Dinic(){ 65 while(mklevel()){ 66 F(i,S,T) cur[i]=head[i]; 67 ans+=dfs(S,INF); 68 } 69 } 70 void init(){ 71 n=getint(); m=getint(); 72 cnt=1; memset(head,0,sizeof head); 73 F(i,1,n) du[i]=0; 74 S=0; T=n+m+2; ans=0; 75 int x,y,z; 76 F(i,1,m){ 77 x=getint(); y=getint(); z=getint(); 78 add(S,i,1); add(i,y+m,1); 79 if (!z) add(i,x+m,1); 80 du[x]++; du[y]++; 81 } 82 F(i,1,n){ 83 if (du[i]%2){puts("impossible");return;} 84 add(i+m,T,du[i]/2); 85 } 86 Dinic(); 87 if (ans==m) puts("possible"); 88 else puts("impossible"); 89 } 90 }G1; 91 int main(){ 92 #ifndef ONLINE_JUDGE 93 freopen("input.txt","r",stdin); 94 // freopen("output.txt","w",stdout); 95 #endif 96 int T=getint(); 97 while(T--) G1.init(); 98 return 0; 99 }