• POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)


    http://poj.org/problem?id=1637

    题意:
    给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路。

    思路:

    构成有向图欧拉回路的要求是入度=出度,无向图的要求是所有顶点的度数为偶数。

    但不管是那个,顶点的度数若是奇数,那都是不能构成的。

    这道题目是非常典型的混合图欧拉回路问题,对于双向边,我们先随便定个向,然后就这样先记录好每个顶点的入度和出度。

    如果有顶点的度数为奇数,可以直接得出结论,是不能构成欧拉回路的。

    那么,如果都是偶数呢?

    因为还会存在入度不等于出度的情况,那么这个时候就要通过改变改变双向边的方向来改变度数。对于每个顶点,如果出度大于入度,那么就将该点与源点相连,容量为(out-in)/2,代表需要改变几条双向边的方向,同理,如果入度大于出度,那么就将该点与汇点相连,容量为(in-out)/2。

    那么,顶点之间如何连接呢?

    对于双向边,将该两个顶点相连,容量为1,代表这条边可以反向一次

    最后,走一遍最大流,如果满流,就说明能够构成欧拉回路。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 using namespace std;
     11 typedef long long LL;
     12 typedef pair<int,int> pll;
     13 const int INF=0x3f3f3f3f;
     14 const int maxn=1000+5;
     15 
     16 struct Edge
     17 {
     18     int from,to,cap,flow;
     19     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
     20 };
     21 
     22 struct Dinic
     23 {
     24     int n,m,s,t;
     25     vector<Edge> edges;
     26     vector<int> G[maxn];
     27     bool vis[maxn];
     28     int cur[maxn];
     29     int d[maxn];
     30 
     31     void init(int n)
     32     {
     33         this->n=n;
     34         for(int i=0;i<n;++i) G[i].clear();
     35         edges.clear();
     36     }
     37 
     38     void AddEdge(int from,int to,int cap)
     39     {
     40         edges.push_back( Edge(from,to,cap,0) );
     41         edges.push_back( Edge(to,from,0,0) );
     42         m=edges.size();
     43         G[from].push_back(m-2);
     44         G[to].push_back(m-1);
     45     }
     46 
     47     bool BFS()
     48     {
     49         queue<int> Q;
     50         memset(vis,0,sizeof(vis));
     51         vis[s]=true;
     52         d[s]=0;
     53         Q.push(s);
     54         while(!Q.empty())
     55         {
     56             int x=Q.front(); Q.pop();
     57             for(int i=0;i<G[x].size();++i)
     58             {
     59                 Edge& e=edges[G[x][i]];
     60                 if(!vis[e.to] && e.cap>e.flow)
     61                 {
     62                     vis[e.to]=true;
     63                     d[e.to]=d[x]+1;
     64                     Q.push(e.to);
     65                 }
     66             }
     67         }
     68         return vis[t];
     69     }
     70 
     71     int DFS(int x,int a)
     72     {
     73         if(x==t || a==0) return a;
     74         int flow=0, f;
     75         for(int &i=cur[x];i<G[x].size();++i)
     76         {
     77             Edge &e=edges[G[x][i]];
     78             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
     79             {
     80                 e.flow +=f;
     81                 edges[G[x][i]^1].flow -=f;
     82                 flow +=f;
     83                 a -=f;
     84                 if(a==0) break;
     85             }
     86         }
     87         return flow;
     88     }
     89 
     90     int Maxflow(int s,int t)
     91     {
     92         this->s=s; this->t=t;
     93         int flow=0;
     94         while(BFS())
     95         {
     96             memset(cur,0,sizeof(cur));
     97             flow +=DFS(s,INF);
     98         }
     99         return flow;
    100     }
    101 }DC;
    102 
    103 int in[maxn],out[maxn];
    104 int u[maxn],v[maxn],w[maxn];
    105 int n,m;
    106 
    107 int main()
    108 {
    109     //freopen("D:\input.txt","r",stdin);
    110     int T;
    111     scanf("%d",&T);
    112     while(T--)
    113     {
    114         scanf("%d%d",&n,&m);
    115         memset(in,0,sizeof(in));
    116         memset(out,0,sizeof(out));
    117         int src=0,dst=n+1;
    118         DC.init(dst+1);
    119 
    120         for(int i=1;i<=m;i++)
    121         {
    122             scanf("%d%d%d",&u[i],&v[i],&w[i]);
    123             out[u[i]]++;
    124             in[v[i]]++;
    125         }
    126 
    127         bool flag=true;
    128         int full_flow=0;
    129         for(int i=1;i<=n;i++)
    130         {
    131             if(((in[i]+out[i])&1))  {flag=false;break;}
    132             if(in[i]>out[i])   {DC.AddEdge(i,dst,(in[i]-out[i])/2);full_flow+=(in[i]-out[i])/2;}
    133             if(out[i]>in[i])   DC.AddEdge(src,i,(out[i]-in[i])/2);
    134         }
    135 
    136         if(flag)
    137         {
    138             for(int i=1;i<=m;i++)
    139                 if(!w[i])  DC.AddEdge(u[i],v[i],1);
    140         }
    141 
    142         if(flag)
    143         {
    144             int flow=DC.Maxflow(src,dst);
    145             if(flow==full_flow)  puts("possible");
    146             else puts("impossible");
    147         }
    148         else puts("impossible");
    149     }
    150     return 0;
    151 }
  • 相关阅读:
    spring注解之@Lazy
    HttpClient之EntityUtils对象
    HTTP协议(Requset、Response)
    SpringBoot SpringSession redis SESSION
    Spring-session redis 子域名 session
    Spring Boot Servlet
    版本管理
    Spring AOP @Aspect
    Spring 事务配置的五种方式
    Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6917356.html
Copyright © 2020-2023  润新知