• 混合图欧拉回路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;
    }
    
  • 相关阅读:
    oo——第三单元总结
    oo第三单元总结
    【BUAA软工】提问回顾与个人总结
    【BUAA软工】HTTP协议前后端实现及实战北航云盘爬取
    【BUAA软工】软件案例分析
    【BUAA软工】结对编程作业
    【BUAA 软工个人项目作业】玩转平面几何
    【BUAA 软工博客作业】个人博客作业
    【BUAA 软工热身作业】继往开来,勇攀高峰
    BUAA-OO-第四单元总结——终章
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3288564.html
Copyright © 2020-2023  润新知