第一次做这种混合图类型的题,看着书上的提示,方法能够想到。自己摸索着做了下。在建图的时候有点技巧,根据图出度和入度转换可以转换为网络流进行做。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> #include<stack> using namespace std; const int inf=1<<29; const int maxn=200; const int maxm=1e4+100; int n,m,e,st,id,des,head[maxn],pnt[maxm],flow[maxm],nxt[maxm],level[maxn],in[maxn],out[maxn]; queue<int> q; vector<pair<int,int> > edges[maxn]; bool vis[maxm]; stack<int> s; void AddEdge(int u,int v,int f) { pnt[e]=v;nxt[e]=head[u];flow[e]=f;head[u]=e++; pnt[e]=u;nxt[e]=head[v];flow[e]=0;head[v]=e++; } bool BFS() { memset(level,0,sizeof(level)); level[st]=1; q.push(st); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nxt[i]) if(flow[i]&&!level[pnt[i]]) { level[pnt[i]]=level[u]+1; q.push(pnt[i]); } } return level[des]; } int DFS(int u,int maxf) { if(u==des||!maxf) return maxf; for(int i=head[u],t;i!=-1;i=nxt[i]) if(level[pnt[i]]==level[u]+1&&(t=DFS(pnt[i],min(flow[i],maxf)))) { flow[i]-=t; flow[i^1]+=t; return t; } return level[u]=0; } int maxflow() { int ans=0; while(BFS()) while(1) { int val=DFS(st,inf); if(!val) break; ans+=val; } return ans; } void DFS(int u) { int num=edges[u].size(); for(int i=0;i<num;i++) { int v=edges[u][i].first; int id=edges[u][i].second; if(vis[id]) continue; vis[id]=1; DFS(v); } s.push(u); } int main() { int T; scanf("%d",&T); while(T--) { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) edges[i].clear(); st=e=0;des=n+1; id=0; for(int i=0;i<m;i++) { int u,v; char s[5]; scanf("%d%d%s",&u,&v,s); in[u]++; out[v]++; if(s[0]=='U') AddEdge(u,v,1); else edges[u].push_back(make_pair(v,id++)); } bool is=true; for(int i=1;i<=n;i++) if((in[i]+out[i])&1) { is=false; break; } if(!is) { printf("No euler circuit exist\n"); if(T) printf("\n"); continue; } int ls=e,sum=0; for(int i=1;i<=n;i++) { if(in[i]<out[i]) { AddEdge(i,des,(out[i]-in[i])/2); } if(in[i]>out[i]) { AddEdge(st,i,(in[i]-out[i])/2); sum+=(in[i]-out[i])/2; } } int val=maxflow(); if(val!=sum) { printf("No euler circuit exist\n"); if(T) printf("\n"); continue; } for(int i=0;i<ls;i+=2) { if(flow[i^1]) { edges[pnt[i]].push_back(make_pair(pnt[i^1],id++)); } else { edges[pnt[i^1]].push_back(make_pair(pnt[i],id++)); } } DFS(1); bool first=true; while(!s.empty()) { if(first) { printf("%d",s.top()); first=false; } else printf(" %d",s.top()); s.pop(); } printf("\n"); if(T) printf("\n"); } return 0; }