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 ...
随机推荐
- cocos2dx常见32种场景切换动画
bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init( ...
- .NETFramework:Stream
ylbtech-.NETFramework:Stream 1.返回顶部 1. #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, Publi ...
- 用 SDL2 处理精灵图
上面就是一个精灵图,由多个固定间隔的图标组成.利用精灵图的好处就是不必将图标逐个读入内存进行操作.我们可以将精灵图中需要的部分用一个个矩形截取下来,然后再输出到渲染器上. 环境:SDL2 + VC++ ...
- 整体二分 HDU - 5808
题目大意 有n个物品,排成一个序列,每个物品有一个di表示取到i要走的距离,vi表示i的价值. 给m组询问[l,r] ,c,sum,问由[l,r]的di<=c的物品能否凑出sum的价值(每个物品 ...
- Get与Post的小知识
Get与Post的小知识 一.传递参数: Get把参数包含在URL中,而在Post通过request body传递参数.因为参数直接暴露在URL上,GET比POST更不安全,所以不能用来传递敏感信息. ...
- FTP服务相关实现
FTP服务的相关实现 vsftpd介绍 1>vsftpd全名为very secure FTP daemon,为非常安全的FTP服务,是针对操作系统的权限来设计的,这个权限是发起者发起该服务进程的 ...
- C++章节练习题
笔试宝典:http://www.bishibaodian.com/writtenCircle/lightquestionlist http://www.bishibaodian.com/written ...
- Codeforces277A 【dfs联通块】
题意: 给出n个人会的语言类型,然后问这n个人里面还需要几个人学习一下语言就可以n个直接互通了.a会1,2,b会2,3,c会4,那么只要C学一下1或者2,或者3就好了...大致就是这个意思. 思路: ...
- MySQL的分支
1.MariaDB MariaDB数据库管理系统是 MySQL 的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MyS ...
- 状压dp小结 By cellur925
会一直慢慢写的... 一.一些技巧(位运算) 取出整数n在二进制表示下的第k位,检验是否为1---(n>>k)&1 求最后完备状态(假设都是1),有n个待枚举状态,结果是(1< ...