• ACM/ICPC 之 混合图的欧拉回路判定-网络流(POJ1637)


    //网络流判定混合图欧拉回路
    //通过网络流使得各点的出入度相同则possible,否则impossible
    //残留网络的权值为可改变方向的次数,即n个双向边则有n次
    //Time:157Ms    Memory:348K
    #include <iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define MAXN 205
    #define INF 0x3f3f3f3f
    int n,m;
    int s,t;
    int dif[MAXN];
    int res[MAXN][MAXN];    //残留网络-代表可变方向数
    int pre[MAXN];
    bool bfs()
    {
        memset(pre,-1,sizeof(pre));
        queue<int> q;
        q.push(s); pre[s] = 0;
        while(!q.empty()){
            int cur = q.front();
            q.pop();
            for(int i = 1; i <= t; i++)
            {
                if(pre[i] == -1 && res[cur][i])
                {
                    pre[i] = cur;
                    if(i == t) return true;
                    q.push(i);
                }
            }
        }
        return false;
    }
    int EK()
    {
        int maxFlow = 0;
        while(bfs()){
            int mind = INF;
            for(int i = t; i != s; i = pre[i])
                mind = min(mind, res[pre[i]][i]);
            for(int i = t; i != s; i = pre[i])
            {
                res[pre[i]][i] -= mind;
                res[i][pre[i]] += mind;
            }
            maxFlow += mind;
        }
        return maxFlow;
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        int T;
        scanf("%d", &T);
        while(T--){
            memset(dif,0,sizeof(dif));
            memset(res,0,sizeof(res));
            scanf("%d%d", &n, &m);
            int total = 0;
            s = 0; t = n+1;
            for(int i = 0; i < m; i++)
            {
                int u,v,t;
                scanf("%d%d%d", &u,&v,&t);
                dif[u]++;   dif[v]--;
                if(t == 0) res[u][v] += 1;  //重边则可变方向+1
            }
            bool flag = true;
            for(int i = 1; i <= n; i++)
            {
                if(dif[i] > 0) {    //出度多-通过源点给予奇数入度
                    res[s][i] = dif[i]/2;
                    total += dif[i]/2;
                }
                if(dif[i] < 0) res[i][t] = -dif[i]/2;  //入度多-通过汇点给予奇数出度
                if(abs(dif[i]) % 2 == 1)
                {
                    flag = false;
                    break;
                }
            }
            (flag && EK() == total)? printf("possible
    "): printf("impossible
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Struts2+Spring+Ibatis集成合并
    spring多个定时任务quartz配置
    Quartz作业调度框架
    百度搜索URL参数含义
    代理IP抓取
    解决HttpWebRequest和HtmlAgilityPack采集网页中文乱码问题
    移动端上传头像-相册、拍摄-旋转
    订单倒计时
    css flex布局 实例
    currentTarget与target
  • 原文地址:https://www.cnblogs.com/Inkblots/p/5714704.html
Copyright © 2020-2023  润新知