题外话:很多混合图问题可以转化为有向图问题(将无向边拆为两条有向边)

本题不行,因为只能经过一次

这种问题能想到网络流。。

复习欧拉回路:入度==出度

和uva1380有点相似,要先给无向边定向。原图为G,定向的边单独组成另一个G’

定向后对任意点,入度==出度,则有了回路。

否则调整原来的无向边。  (如果入度出度奇偶性不同,则无解)

出度增加(in-out/2)。

注意U->V变成V->U,U出度-1,V出度+1. 就像在运送”出度”,就是网络流。(满足out>in的点能提供出度) (可以提供的出度为diff[i]/2,需要接受的出度为-diff[i]/2)

原有的边cap为1(只能改一次方向)

设立超级节点S,T,S连可以提供的节点,cap为可以提供的出度

T类似。

当sum可以提供的出度!=MaxFlow,就无解。否则有解(必须提供出去。这里可以证明提供出去后所有的点in==out)

char dir[9];

scanf("%d%d%s", &u[i], &v[i], dir);    0 1 D

感觉可以做一个处理输入的专题了...

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int INF = ; struct Edge {
int from, to, cap, flow;
Edge(int u, int v, int c, int f):from(u),to(v),cap(c),flow(f) {}
}; const int maxn = +; struct EdmondsKarp {
int n, m;
vector<Edge> edges; // 边数的两倍
vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
int a[maxn]; // 当起点到i的可改进量
int p[maxn]; // 最短路树上p的入弧编号 void init(int n) {
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap) {
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} int Maxflow(int s, int t) {
int flow = ;
for(;;) {
memset(a, , sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(!a[e.to] && e.cap > e.flow) {
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap-e.flow);
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
flow += a[t];
}
return flow;
}
}; EdmondsKarp g; const int maxm = + ; int n, m, u[maxm], v[maxm], directed[maxm], id[maxm], diff[maxn]; vector<int> G[maxn];
vector<int> vis[maxn];
vector<int> path; void euler(int u) {
for(int i = ; i < G[u].size(); i++)
if(!vis[u][i]) {
vis[u][i] = ;
euler(G[u][i]);
path.push_back(G[u][i]+);
}
} void print_answer() {
// build the new graph
for(int i = ; i < n; i++) { G[i].clear(); vis[i].clear(); }
for(int i = ; i < m; i++) {
bool rev = false;
if(!directed[i] && g.edges[id[i]].flow > ) //id记录了无向边在edges中的位置
rev = true; //G记录边的起点对应的终点
if(!rev) //没有变反向
{ G[u[i]].push_back(v[i]);
vis[u[i]].push_back();
}
else {
G[v[i]].push_back(u[i]);
vis[v[i]].push_back();
}
} // print euler tour
path.clear();
euler(); //因为节点一记为了0 printf("");
for(int i = path.size()-; i >= ; i--) printf(" %d", path[i]);
printf("\n");
} int main() {
int T;
scanf("%d", &T); while(T--) {
scanf("%d%d", &n, &m);
g.init(n+); memset(diff, , sizeof(diff));
for(int i = ; i < m; i++) {
char dir[];
scanf("%d%d%s", &u[i], &v[i], dir);
u[i]--;
v[i]--;
directed[i] = (dir[] == 'D' ? : );
diff[u[i]]++; //出度-入度
diff[v[i]]--;
if(!directed[i]) { id[i] = g.edges.size(); g.AddEdge(u[i], v[i], ); }
} bool ok = true;
for(int i = ; i < n; i++)
if(diff[i] % != ) { ok = false; break; } int s = n, t = n+;
if(ok) {
int sum = ;
for(int i = ; i < n; i++) { if(diff[i] > ) {
g.AddEdge(s, i, diff[i]/);
sum += diff[i]/;
} if(diff[i] < ) {
g.AddEdge(i, t, -diff[i]/); }
} if(g.Maxflow(s, t) != sum)
ok = false;
} if(!ok)
printf("No euler circuit exist\n");
else
print_answer(); // underlying graph is always connected if(T)
printf("\n");
}
return ;
}

uva10735 Euler Circuit的更多相关文章

  1. UVA-10735 - Euler Circuit(混合欧拉回路输出)

    题意:给你一个图,有N个点,M条边,这M条边有的是单向的,有的是双向的. 问你能否找出一条欧拉回路,使得每条边都只经过一次! 分析: 下面转自别人的题解: 把该图的无向边随便定向,然后计算每个点的入度 ...

  2. poj2284 That Nice Euler Circuit(欧拉公式)

    题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k( ...

  3. POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)

                                                          That Nice Euler Circuit Time Limit: 3000MS   M ...

  4. UVa 10735 (混合图的欧拉回路) Euler Circuit

    题意: 给出一个图,有的边是有向边,有的是无向边.试找出一条欧拉回路. 分析: 按照往常的思维,遇到混合图,我们一般会把无向边拆成两条方向相反的有向边. 但是在这里却行不通了,因为拆成两条有向边的话, ...

  5. UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)

    题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制 ...

  6. Uva 1342 - That Nice Euler Circuit

    Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his ...

  7. UVALive - 3263 That Nice Euler Circuit (几何)

    UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址:  UVALive - 3263 That Nice Euler Circuit 题意:  给 ...

  8. Euler Circuit UVA - 10735(混合图输出路径)

    就是求混合图是否存在欧拉回路 如果存在则输出一组路径 (我就说嘛 咱的代码怎么可能错.....最后的输出格式竟然w了一天 我都没发现) 解析: 对于无向边定向建边放到网络流图中add(u, v, 1) ...

  9. That Nice Euler Circuit(LA3263+几何)

    That Nice Euler Circuit Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu D ...

随机推荐

  1. Python测试框架doctest

    doctest是python自带的一个模块.本博客将介绍doctest的两种使用方式:一种是嵌入到python源码中,另外一种是放到一个独立文件. doctest 的概念模型 在python的官方文档 ...

  2. 【前端】CentOS 7 系列教程之四: 配置 git 服务器自动部署

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_4.html 安装pm2守护进程,备用 npm install -g pm2 创建/srv/www文件夹 ...

  3. 移动端网页巧用 margin和padding 的百分比实现自适应

    一个基础却又容易混淆的css知识点 本文依赖于一个基础却又容易混淆的css知识点:当margin/padding取形式为百分比的值时,无论是left/right,还是top/bottom,都是以父元素 ...

  4. C++实现查找链表中环的入口节点

    /* * 寻找链表中环的入口节点.cpp * * Created on: 2018年4月10日 * Author: soyo */ #include<iostream> using nam ...

  5. 收藏产品判断、html 在 UIwebView里面显示

     收藏产品功能 要求:用户点击收藏,如果已经收藏,用户点击就取消收藏 写法一: 点击事件{ if (!isSelect) { [sender setImage:[UIImage imageNamed: ...

  6. Hibernate自定义字段查询

    关于Hibernate自定义字段查询的方法,网上有很多,我这里就不详细写了,只把几个查询方法的注意事项说明一下. 废话少说, 进入正题: 假设有2个实体对象,Institution和User,结构与配 ...

  7. 【215】◀▶ IDL 文件操作说明 (黑底)

    参考:I/O - General File Access Routines —— 基本文件操作函数 01   CD 修改当前的工作空间路径. 02   FILE_SEARCH 对文件名进行特定的查找. ...

  8. Codeforces Round #422 (Div. 2)D. My pretty girl Noora(递推+数论)

    传送门 题意 对于n个女孩,每次分成x人/组,每组比较次数为\(\frac{x(x+1)}{2}\),直到剩余1人 计算\[\sum_{i=l}^{r}t^{i-l}f(i)\],其中f(i)代表i个 ...

  9. 屏蔽QQ黄钻官方团队送礼物的方法

    按照在网上查到的方法: 登录手机QQ \(\longrightarrow\) 好友动态 \(\longrightarrow\) 个人主页 \(\longrightarrow\) 右上角三道杠 \(\l ...

  10. vim normal 模式下L键

    vim normal 模式下L键总是到一行的最后一个字符,而不是最后一个字符的下一个字符,这样进入插入模式,就还得往右移动一下,就很费劲? 怎么解决 更新: a键进入插入即可