zoukankan      html  css  js  c++  java
  • 混合图欧拉回路POJ1637Sightseeing tour

    http://www.cnblogs.com/looker_acm/archive/2010/08/15/1799919.html

    /*
    **  混合图欧拉回路
    **  只记录各定点的出度与入度之差,有向边无用丢弃,将无向边定向,在网络中建立流量为1的边
    **  另新建s和t。对于入 > 出的点u,连接边(u, t)、容量为x,对于出 > 入的点v,连接边(s, v),
    **  容量为x(注意对不同的点x不同)。之后,察看是否有满流的分配,如果是满流则存在,否则不存在
    */
    
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    using namespace std;
    const int maxn = 300;
    const int maxm = maxn*10;
    struct node{
        int v,next,flow;
    }edge[maxm];
    int head[maxn],dis[maxn],deg[maxn];
    int id,source,sink;
    void add_edge(int u,int v,int flow){
        edge[id].v = v;edge[id].flow = flow;edge[id].next = head[u];head[u] = id++;
        edge[id].v = u;edge[id].flow =  0  ;edge[id].next = head[v];head[v] = id++;
    }
    bool spfa(){
        memset(dis,-1,sizeof(dis));
        dis[source] = 0;
        queue<int>que;
        que.push(source);
        while(!que.empty()){
            int u = que.front();
            que.pop();
            for(int id = head[u]; id != -1; id = edge[id].next){
                int v = edge[id].v;
                if( edge[id].flow > 0 && dis[v] == -1){
                    dis[v] = dis[u] + 1;
                    que.push(v);
                }
            }
        }
        return dis[sink] != -1;
    }
    
    int dinic(int u,int flow){
        if( u == sink)return flow;
        int tmp = flow;
        for(int id = head[u]; id != -1; id = edge[id].next){
            int v = edge[id].v;
            if( edge[id].flow > 0 && dis[v] == dis[u] + 1){
                int  tt = dinic(v,min(edge[id].flow ,tmp));
                tmp -= tt;
                edge[id].flow -= tt;
                edge[id^1].flow += tt;
                if( tmp == 0)return flow;
            }
        }
        return flow - tmp;
    }
    int get_max(){
        int max_flow = 0;
        while( spfa())
        max_flow += dinic(source,100000);
        return max_flow;
    }
    int main(){
        int t,n,m;
        int u,v,d;
        scanf("%d",&t);
        while( t-- ){
            scanf("%d%d",&n,&m);
            for(int i = 0; i <= n+1; i++)
            deg[i] = 0,head[i] = -1;
            id = source = 0;sink = n+1;
            while( m-- ){
                scanf("%d%d%d",&u,&v,&d);
                if( u == v)continue;
                deg[u]++,deg[v]--;
                if( d == 0)add_edge(u,v,1);
            }
            bool flg = false;
            int ans = 0;
            for(int i = 1;i <= n; i++){
                if( deg[i]%2 ){flg = true;break;}
                deg[i] /= 2;
                if( deg[i] > 0){
                    ans += deg[i];
                    add_edge(source,i,deg[i]);
                }
                else
                add_edge(i,sink,-deg[i]);
            }
            if( flg || ans != get_max())puts("impossible");
            else puts("possible");
    
        }
        return 0;
    }
    
  • 相关阅读:
    java笔试之数字颠倒
    java笔试之取近似值
    java笔试之求int型正整数在内存中存储时1的个数
    js日期格式化Date
    【算法导论C++代码】归并排序
    Unity3D 错误nativeVideoFrameCallback的解决方法
    Unity3D脚本(MonoBehaviour)生命周期分析
    Unity3D 移动MM failed to find resource file{mmiap.xml}解
    Unity3D C#打开外部应用程序,并检测应用程序是否关闭退出
    Unity3d脚本执行顺序详解
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3288564.html
Copyright © 2011-2022 走看看