uva10735 Euler Circuit
题外话:很多混合图问题可以转化为有向图问题(将无向边拆为两条有向边)
本题不行,因为只能经过一次
这种问题能想到网络流。。
复习欧拉回路:入度==出度
和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的更多相关文章
- UVA-10735 - Euler Circuit(混合欧拉回路输出)
题意:给你一个图,有N个点,M条边,这M条边有的是单向的,有的是双向的. 问你能否找出一条欧拉回路,使得每条边都只经过一次! 分析: 下面转自别人的题解: 把该图的无向边随便定向,然后计算每个点的入度 ...
- poj2284 That Nice Euler Circuit(欧拉公式)
题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k( ...
- POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)
That Nice Euler Circuit Time Limit: 3000MS M ...
- UVa 10735 (混合图的欧拉回路) Euler Circuit
题意: 给出一个图,有的边是有向边,有的是无向边.试找出一条欧拉回路. 分析: 按照往常的思维,遇到混合图,我们一般会把无向边拆成两条方向相反的有向边. 但是在这里却行不通了,因为拆成两条有向边的话, ...
- UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)
题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制 ...
- Uva 1342 - That Nice Euler Circuit
Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his ...
- UVALive - 3263 That Nice Euler Circuit (几何)
UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址: UVALive - 3263 That Nice Euler Circuit 题意: 给 ...
- Euler Circuit UVA - 10735(混合图输出路径)
就是求混合图是否存在欧拉回路 如果存在则输出一组路径 (我就说嘛 咱的代码怎么可能错.....最后的输出格式竟然w了一天 我都没发现) 解析: 对于无向边定向建边放到网络流图中add(u, v, 1) ...
- That Nice Euler Circuit(LA3263+几何)
That Nice Euler Circuit Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu D ...
随机推荐
- 深入理解js里面的this
闲聊两句(可以忽略): 毕业有半年了,时间还过得真快,不过还好,感觉自己相对于刚毕业那会确实成长了很多:好久没有打游戏了(自己决心要戒掉的),消磨时光的时候就看看电影或者追追电视剧,再无聊就洗洗衣服. ...
- 【204】显示3D大球球
1. 光滑球 From Jan 28, 2016 2. 大球球 https://www.revolvermaps.com/?target=enlarge&i=0xoqkxnu52c&a ...
- View Programming Guide for iOS ---- iOS 视图编程指南(二)---View and Window Architecture
View and Window Architecture 视图和窗口架构 Views and windows present your application’s user interface and ...
- 862. Shortest Subarray with Sum at Least K
Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K. If there ...
- 第二篇 .NET高级技术之密闭类和静态类及扩展方法
1.密闭类是修饰为sealed的类, sealed不能有子类.一般只有系统中的一些基本类声明为sealed.面试题:是否可以编写一个类继承自String类? 答:不能,因为string被声明为了sea ...
- Zookeeper的多节点集群详细启动步骤(3或5节点)
分为 (1)分别去3或5节点上去启动Zookeeper进程 (2)自己写个脚本,直接在主节点上去启动Zookeeper进程. (1)分别去3或5节点上去启动Zookeeper进程 第一步: [hado ...
- iOS 获取当前响应链的First Responder (Swift)
import UIKit private weak var currentFirstResponder: AnyObject? extension UIResponder { static func ...
- Spring 2.5
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service 和 @Controller.在目前的 Spring ...
- 如何用Python在10分钟内建立一个预测模型
转载自:https://baijia.baidu.com/s?old_id=307995 最近,我从孙子(指<孙子兵法>——译者注)那里学到了一些策略:速度和准备 “兵之情主速,乘人之不及 ...
- Codeforces Round #261 (Div. 2) D
Description Parmida is a clever girl and she wants to participate in Olympiads this year. Of course ...