zoukankan      html  css  js  c++  java
  • poj1637 Sightseeing tour 混合图欧拉回路判定

      传送门

    第一次做这种题, 尽管ac了但是完全不知道为什么这么做。

    题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路。

    做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个方向, 然后连一条边, 权值为1。 最后统计入度出度, 如果一个点的(入度-出度)%2==1, 就说明不存在欧拉回路。 如果全都满足, 就判断每个点的入度出度的大小关系, 入度>出度, 就向汇点连一条边, 权值为(入度-出度)/2, 相反的话就向源点连边。

    跑一遍最大流, 看是否满流, 如果满流就说明存在。

    完全不理解.....还是太弱。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define pb(x) push_back(x)
      4 #define ll long long
      5 #define mk(x, y) make_pair(x, y)
      6 #define lson l, m, rt<<1
      7 #define mem(a) memset(a, 0, sizeof(a))
      8 #define rson m+1, r, rt<<1|1
      9 #define mem1(a) memset(a, -1, sizeof(a))
     10 #define mem2(a) memset(a, 0x3f, sizeof(a))
     11 #define rep(i, a, n) for(int i = a; i<n; i++)
     12 #define ull unsigned long long
     13 typedef pair<int, int> pll;
     14 const double PI = acos(-1.0);
     15 const double eps = 1e-8;
     16 const int mod = 1e9+7;
     17 const int inf = 1061109567;
     18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     19 const int maxn = 210;
     20 const int maxE = 10005;
     21 int indeg[maxn], outdeg[maxn];
     22 int head[maxE], s, t, num, q[maxE], dis[maxn];
     23 struct node
     24 {
     25     int to, nextt, c;
     26 }e[maxE];
     27 void init() {
     28     mem1(head);
     29     num = 0;
     30     mem(indeg);
     31     mem(outdeg);
     32 }
     33 void add(int u, int v, int c) {
     34     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
     35     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
     36 }
     37 int bfs() {
     38     mem(dis);
     39     int st = 0, ed = 0;
     40     q[ed++] = s;
     41     dis[s] = 1;
     42     while(st<ed) {
     43         int u = q[st++];
     44         for(int i = head[u]; ~i; i = e[i].nextt) {
     45             int v = e[i].to;
     46             if(e[i].c&&!dis[v]) {
     47                 dis[v] = dis[u]+1;
     48                 if(v == t)
     49                     return 1;
     50                 q[ed++] = v;
     51             }
     52         }
     53     }
     54     return 0;
     55 }
     56 int dfs(int u, int limit) {
     57     if(u == t)
     58         return limit;
     59     int cost = 0;
     60     for(int i = head[u]; ~i; i = e[i].nextt) {
     61         int v = e[i].to;
     62         if(e[i].c&&dis[v] == dis[u]+1) {
     63             int tmp = dfs(v, min(limit-cost, e[i].c));
     64             if(tmp>0) {
     65                 e[i].c -= tmp;
     66                 e[i^1].c += tmp;
     67                 cost += tmp;
     68                 if(limit == cost)
     69                     break;
     70             } else {
     71                 dis[v] = -1;
     72             }
     73         }
     74     }
     75     return cost;
     76 }
     77 int dinic() {
     78     int ans = 0;
     79     while(bfs()) {
     80         ans += dfs(s, inf);
     81     }
     82     return ans;
     83 }
     84 int main()
     85 {
     86     int T, n, m, x, y, z;
     87     cin>>T;
     88     while(T--) {
     89         scanf("%d%d", &n, &m);
     90         init();
     91         s = 0, t = n+1;
     92         while(m--) {
     93             scanf("%d%d%d", &x, &y, &z);
     94             indeg[y]++;
     95             outdeg[x]++;
     96             if(z == 0) {
     97                 add(x, y, 1);
     98             }
     99         }
    100         int flag = 0;
    101         for(int i = 1; i<=n; i++) {
    102             if(abs(indeg[i]-outdeg[i])%2==1) {
    103                 flag = 1;
    104                 break;
    105             }
    106         }
    107         if(flag) {
    108             cout<<"impossible"<<endl;
    109             continue;
    110         }
    111         int sum = 0;
    112         for(int i = 1; i<=n; i++) {
    113             if(indeg[i]<outdeg[i]) {
    114                 add(s, i, (outdeg[i]-indeg[i])/2);
    115             } else {
    116                 add(i, t, (indeg[i]-outdeg[i])/2);
    117                 sum += (indeg[i]-outdeg[i])/2;
    118             }
    119         }
    120         int ans = dinic();
    121         if(ans == sum) {
    122             cout<<"possible"<<endl;
    123         } else {
    124             cout<<"impossible"<<endl;
    125         }
    126     }
    127 }
  • 相关阅读:
    aop日志记录
    RocketMQ 启动停止命令
    windows搭建RocketMQ服务
    zTree实战
    springboot 传List参数
    Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)
    SpringBoot Controller接收参数的几种常用方
    clob大数据转换为多行数据
    oracle dba学习
    TreeNode(包含读出文件里的信息)
  • 原文地址:https://www.cnblogs.com/yohaha/p/5011399.html
Copyright © 2011-2022 走看看