https://www.luogu.org/problem/UVA10735
题目大意:给出一个
V
(
V
<
=
100
)
V(V<=100)
V(V<=100)个点和
E
(
E
<
=
500
)
E(E<=500)
E(E<=500) 条边的无向边与有向边的混合图,试打印出它的任意一条欧拉回路(无向边的两个方向只能从某个方向经过一次),如果没有输出
N
o
e
u
l
e
r
c
i
r
c
u
i
t
e
x
i
s
t
No\ \ euler \ \ circuit\ \ exist
No euler circuit exist。输入保证图连通。
思路:参见https://blog.csdn.net/xiji333/article/details/99655634
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
int to,nxt,f;
};
Edge edge[2005];
int id[2005];
int head[105],cur[105];
int depth[105];
int x[505],y[505],d[505],re[4005],adm[105][105];
char op[10];
int n,m,s,t,len,tot=1;
vector<int> vec[105];
inline void addedge(int u,int v,int dis)
{
edge[++tot].to=v,edge[tot].f=dis;
edge[tot].nxt=head[u];
head[u]=tot;
edge[++tot].to=u,edge[tot].f=0;
edge[tot].nxt=head[v];
head[v]=tot;
}
bool bfs()
{
memcpy(cur,head,sizeof(cur));
memset(depth,0,sizeof(depth));
queue<int> q;
depth[s]=1;//源点
q.push(s);
int fir,to;
while(!q.empty())
{
fir=q.front();
q.pop();
for(int i=head[fir];i;i=edge[i].nxt)
{
to=edge[i].to;
if(edge[i].f&&!depth[to])
{
depth[to]=depth[fir]+1;
q.push(to);
}
}
}
return depth[t];
}
int dfs(int u,int lim)//当前节点 当前流量
{
if(u==t)//汇点
return lim;
int v,temp,ans=0;
for(int i=cur[u];i;i=edge[i].nxt)
{
cur[u]=i; //当前弧优化
v=edge[i].to;
if(depth[v]==depth[u]+1&&edge[i].f)
{
temp=dfs(v,min(lim,edge[i].f));
edge[i].f-=temp;
edge[i^1].f+=temp;
ans+=temp;
lim-=temp;
if(!lim)
break;
}
}
if(!ans)
depth[u]=0;
return ans;
}
int dinic()
{
int ans=0;
while(bfs())
ans+=dfs(s,INF);
return ans;
}
void euler(int v)
{
for(int i=1;i<=n;i++)
{
if(adm[v][i])
{
--adm[v][i];
euler(i);
}
}
re[++len]=v;
}
int main()
{
int times;
scanf("%d",×);
while(times--)
{
memset(d,0,sizeof(d));
memset(id,0,sizeof(id));
memset(head,0,sizeof(head));
tot=1;
scanf("%d %d",&n,&m);
s=0,t=n+1;
for(int i=0;i<m;i++)
{
scanf("%d %d %s",&x[i],&y[i],op);
++d[x[i]],--d[y[i]];
if(op[0]=='U')//给无向边定向
id[i]=tot+1,addedge(x[i],y[i],1);
else
id[i]=-1;
}
bool flag=1;
int sum=0;
for(int i=1;i<=n;i++)
{
if(d[i]&1)
flag=0;
d[i]/=2;
if(d[i]>0)
{
addedge(s,i,d[i]);
sum+=d[i];
}
else
addedge(i,t,-d[i]);
}
if(!flag)
printf("No euler circuit exist\n");
else
{
int ans=dinic();
if(ans!=sum)
printf("No euler circuit exist\n");
else
{
len=0;
memset(adm,0,sizeof(adm));
for(int i=0;i<m;i++)
{
if(id[i]>0&&!edge[id[i]].f)//需要反向的无向边
++adm[y[i]][x[i]];
else
++adm[x[i]][y[i]];
}
euler(1);
printf("%d",re[len]);
for(int i=len-1;i>=1;i--)
printf(" %d",re[i]);
printf("\n");
}
}
if(times)
printf("\n");
}
return 0;
}