[POJ1637]Sightseeing tour 混合图欧拉回路 做题笔记
2016-03-07 12:20
344 查看
题目链接:http://poj.org/problem?id=1637
这题是混合图欧拉回路,可以用网络流来做。
自己还是太弱了,这里引用一下hzwer的思路
混合图欧拉回路
设点x的出度-入度为d[x]
对于无向图先任意定向,若任意x,d[x]非偶数则impossible
d[x]/2即为连接每个点的边需要反向的数量
若d[x]/2>0 连S->T 容量d[x]/2
否则d[x]/2<0 连 x->T 容量-d[x]/2
舍弃有向边,将定向后的无向边放进网络流图中
判最大流是否等于∑ d[x]/2
如果不明白为什么这样建图可以参考/article/4679641.html
另外还有个好东西:网络流建模总结
这题是混合图欧拉回路,可以用网络流来做。
自己还是太弱了,这里引用一下hzwer的思路
混合图欧拉回路
设点x的出度-入度为d[x]
对于无向图先任意定向,若任意x,d[x]非偶数则impossible
d[x]/2即为连接每个点的边需要反向的数量
若d[x]/2>0 连S->T 容量d[x]/2
否则d[x]/2<0 连 x->T 容量-d[x]/2
舍弃有向边,将定向后的无向边放进网络流图中
判最大流是否等于∑ d[x]/2
如果不明白为什么这样建图可以参考/article/4679641.html
另外还有个好东西:网络流建模总结
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N=250,M=10009,inf=0x3fffffff; int du ,d ,head ,ver[M<<1],e[M<<1],next[M<<1]; int n,m,s,t,tot=1,cnt=0,maxflow=0; int read () { int x=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar(); } return x; } void add (int u,int v,int w) { ver[++tot]=v;e[tot]=w;next[tot]=head[u];head[u]=tot; ver[++tot]=u;e[tot]=0;next[tot]=head[v];head[v]=tot; } bool bfs () { queue<int> q; memset(d,0,sizeof(d)); q.push(s); d[s]=1; while (!q.empty()) { int x=q.front(); q.pop(); for (int i=head[x];i;i=next[i]) if (e[i]&&!d[ver[i]]) { q.push(ver[i]); d[ver[i]]=d[x]+1; if (ver[i]==t) return 1; } } return 0; } int dinic (int x,int f) { int rest=f; if (x==t) return f; for (int i=head[x];i&&rest;i=next[i]) if (e[i]&&d[ver[i]]==d[x]+1) { int now=dinic(ver[i],min(e[i],rest)); if (!now) d[ver[i]]=0;// e[i]-=now; e[i^1]+=now; rest-=now; } return f-rest; } bool jud () { for (int i=1;i<=n;i++) if (du[i]%2!=0) return 0; return 1; } int main () { int u,v,w,tmp=0; int T=read(); while (T--) { tot=1;cnt=maxflow=0; memset(head,0,sizeof(head)); memset(du,0,sizeof(du)); n=read(); m=read(); s=0,t=n+1; for (int i=1;i<=m;i++) { u=read(); v=read(); w=read(); du[u]--,du[v]++; if (!w) add(v,u,1); } for (int i=1;i<=n;i++) { if (du[i]<0) add(i,t,-du[i]/2); if (du[i]>0) add(s,i,du[i]/2),cnt+=du[i]/2; } if (!jud()) { puts("impossible");continue; } while (bfs()) while (tmp=dinic(s,inf)) maxflow+=tmp; if (cnt!=maxflow) puts("impossible"); else puts("possible"); } return 0; }
相关文章推荐
- java经典面试题struts,hibernate,spring
- 《从零开始学Swift》学习笔记(Day 57)——Swift编码规范之注释规范:
- hdu 5630 Rikka with Chess
- ssh建立后门的两种方法
- 启动Mediation_Function失败及解决方案
- 关于查找iOS中App路径时所要注意的一个问题
- 关于查找iOS中App路径时所要注意的一个问题
- 不同VLAN之间相互通信的两种方式(单臂路由、三层交换)
- 关于查找iOS中App路径时所要注意的一个问题
- TokuDB的索引结构–分形树的实现
- Android中的EditText默认时不弹出软键盘的方法
- Maven教程-使用Nexus搭建私服
- 修改JAVA_HOME无效,java版本保持不变的问题解决
- Snackbar 的使用 Toast加强版
- 帧动画处理脚本
- Jenkins自动构建
- bootstrap 分页
- ARP代理(Proxy ARP)
- Java中的字符集编码入门-增补字符
- Java数据类型和MySql数据类型对应表