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

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

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

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

和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. 2018.8.10Yukimai模拟Day1

    这的确是最惨的一次模拟了……不会再惨了(10pts除非爆零orz) 总结一下吧…… T1 .章鱼 众所周知,雪舞喵有许多猫.由于最近的天气十分炎热,雪舞城的大魔法师雪月月根本不想出门,只想宅在家里打隔 ...

  2. Python项目使用memcached缓存

    前言许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现数据库的负担加重.数据库响应恶化. 网站显示延 ...

  3. Linux网络编程笔记(修订版)

    我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1.   基本概念 2.   基本接口 2.1.   打开一个socket 2.2.   将 ...

  4. bzoj 4987 Tree —— 树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4987 其实就是在树上找有 k 个点的连通块(路径上的点都选是最优的),之间的边都走了两遍,只 ...

  5. Sublime Text3 python代码去除白色框框

    之所以会出现白色框框,是因为代码不符合PEP8规范!!! 可以装一个 AUTOPEP8 插件,然后按 Ctrl + Alt + r 就会自动帮你PEP8格式化,白色框框就会消失了... 这是原来的博文 ...

  6. POJ3258【二分】

    题意: 问一个河岸,两岸之间有笔直的n块石头,然后拔起(也可以施展魔法)m个石块,假设两岸也是石块,求处理过的石块的最小距离的最大. 思路: 他让我们求移开m个石块,无非是在n+2-m(已经把两岸看成 ...

  7. poj 3294 Life Forms【SA+二分】

    先加入未出现字符间隔把n个串连起来,注意如果串开的char这个间隔字符不能溢出,把这个接起来的串跑SA,二分答案k,判断的时候把连续一段he>=k的分成一组,然后看着一段是否包含了>n/2 ...

  8. P1228-重叠的图像

    一道很水的topsort,唉?怎么交了14遍...(某人用我的代码刚好卡过,我怎么过不去...[鄙视][鄙视][鄙视]) #include <bits/stdc++.h> using na ...

  9. VS2019+ASP.NETCore+图表

    原帖学习踩坑:https://www.cnblogs.com/fzqm-lwz/p/9704973.html,主要根据大佬原帖内容,实现尝试,进行一些修改: 实现方式一:通过标记帮助程序将JS代码传到 ...

  10. 51Nod 1179 最大的最大公约数(暴力大法好)

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; ; in ...