标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9100 | Accepted: 3830 |
Description
Input
Output
Sample Input
4 5 8 2 1 0 1 3 0 4 1 1 1 5 0 5 4 1 3 4 0 4 2 1 2 2 0 4 4 1 2 1 2 3 0 3 4 0 1 4 1 3 3 1 2 0 2 3 0 3 2 0 3 4 1 2 0 2 3 1 1 2 0 3 2 0
Sample Output
possible impossible impossible possible
【分析】
给出一张混合图(有有向边,也有无向边),判断是否存在欧拉回路。
首先是对图中的无向边随意定一个方向,然后统计每个点的入度(indeg)和出度(outdeg),如果(indeg - outdeg)是奇数的话,一定不存在欧拉回路;
如果所有点的入度和出度之差都是偶数,那么就开始网络流构图:
1,对于有向边,舍弃;对于无向边,就按照最开始指定的方向建权值为 1 的边(不一定是1,应该是这条边出现的次数,因为可能重边,我就是在这个地方WA了);
2,对于入度小于出度的点,从源点连一条到它的边,权值为(outdeg - indeg)/2;出度小于入度的点,连一条它到汇点的权值为(indeg - outdeg)/2 的边;
构图完成,如果满流(求出的最大流值 == 和汇点所有连边的权值之和),那么存在欧拉回路,否则不存在。
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 10000 typedef long long ll; using namespace std; const int N=405; const int M=300005; int power(int a,int b,int c){int ans=1;while(b){if(b%2==1){ans=(ans*a)%c;b--;}b/=2;a=a*a%c;}return ans;} struct man { int c,f; }w[N][N]; int dis[N],n,m; int t,cnt,maxn,ans; int in[N],out[N]; bool flag; bool bfs() { queue<int>q; memset(dis,0,sizeof(dis)); q.push(0); dis[0]=1; while(!q.empty() && !dis[t]){ int v=q.front();q.pop(); for(int i=1;i<=t;i++){ //if(i==t)printf("w[i][t].c=%d\n",w[i][t].c); if(!dis[i]&&w[v][i].c>w[v][i].f){ q.push(i); dis[i]=dis[v]+1; } } } return dis[t]!=0; } int dfs(int cur,int cp) { if(cur==t||cp==0)return cp; int tmp=cp,tt; for(int i=1;i<=t;i++){ if(dis[i]==dis[cur]+1 &&w[cur][i].c>w[cur][i].f){ tt=dfs(i,min(w[cur][i].c-w[cur][i].f,tmp)); w[cur][i].f+=tt; w[i][cur].f-=tt; tmp-=tt; } } return cp-tmp; } void dinic() { ans=0; while(bfs())ans+=dfs(0,inf); if(ans==maxn)puts("possible"); else puts("impossible"); } void init() { int a,b,d; scanf("%d%d",&n,&m);t=n+1; for(int i=1;i<=n;i++)in[i]=out[i]=0; while(m--){ scanf("%d%d%d",&a,&b,&d); if(d==0)w[a][b].c++;//有重边,若把它赋值为1,WA out[a]++;in[b]++; } } void solve() { flag=true; for(int i=1;i<=n;i++){ if((in[i]-out[i])&1){ puts("impossible");flag=false;return; } if(in[i]<out[i])w[0][i].c=(out[i]-in[i])/2; else if(in[i]>out[i])w[i][t].c=(in[i]-out[i])/2,maxn+=(in[i]-out[i])/2; } } int main(){ int T; scanf("%d",&T); while(T--){ memset(w,0,sizeof(w)); maxn=0; init(); solve(); if(flag) dinic(); } return 0; }
POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5836259.html