P2764-最小路径覆盖问题

  1 #include<bits/stdc++.h>
  2 #define _for(i,a,b) for(register int i = (a);i < b;i ++)
  3 #define _rep(i,a,b) for(register int i = (a);i > b;i --)
  4 #define INF 0x3f3f3f3f
  5 #define MOD 100000000
  6 #define maxn 100003
  7 #define pb push_back
  8 #define debug() printf("Miku Check OK!\n")
  9 typedef long long ll;
 10 
 11 using namespace std;
 12 typedef pair<int,int> P;
 13 inline ll read()
 14 {
 15     ll ans = 0;
 16     char ch = getchar(), last = ' ';
 17     while(!isdigit(ch)) last = ch, ch = getchar();
 18     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
 19     if(last == '-') ans = -ans;
 20     return ans;
 21 }
 22 inline void write(ll x)
 23 {
 24     if(x < 0) x = -x, putchar('-');
 25     if(x >= 10) write(x / 10);
 26     putchar(x % 10 + '0');
 27 }
 28 int ver[maxn],Next[maxn],head[maxn],val[maxn];
 29 int d[maxn];
 30 int n,m,s,t,tot,maxflow;
 31 void add(int x,int y,int w)
 32 {
 33     ver[++tot] = y,Next[tot] = head[x],head[x] = tot,val[tot] = w;
 34 }
 35 bool bfs()
 36 {
 37     memset(d,0,sizeof(d));
 38     queue<int> q;
 39     q.push(s);d[s] = 1;
 40     while(!q.empty())
 41     {
 42         int x = q.front();q.pop();
 43         for(int i = head[x]; i; i = Next[i])
 44             if(val[i] && !d[ver[i]])
 45             {
 46                 q.push(ver[i]);
 47                 d[ver[i]] = d[x]+1;
 48                 if(ver[i]==t)
 49                     return true;
 50             }
 51     }
 52     return false;
 53 }
 54 int dinic(int x,int flow)
 55 {
 56     if(x==t) return flow;
 57     // k为子节点增量 
 58     int rest = flow, k;
 59     for(int i = head[x]; i && rest; i = Next[i])
 60     {
 61         if(val[i] && d[ver[i]] == d[x]+1)
 62         {
 63             k = dinic(ver[i],min(rest,val[i]));
 64             if(!k) d[ver[i]] = 0;
 65             val[i] -= k;
 66             val[i^1] += k;
 67             rest -= k;
 68         }
 69     }
 70     return flow - rest;
 71 }
 72 vector<int> st;
 73 int vvis[maxn];
 74 void go(int i,vector<int>& rnt)
 75 {
 76     rnt.pb(i);
 77     for(int j = head[i]; j ; j = Next[j])
 78     {
 79         int y = ver[j];
 80         if(y>n && !vvis[y-n] && !val[j])
 81         {
 82             vvis[y-n] = 1;
 83             go(y-n,rnt);
 84         }
 85     }
 86 }
 87 int main()
 88 {
 89     n = read();m = read();
 90     tot = 1;maxflow = 0;s = 0;t = 2*n+1;
 91     _for(i,1,m+1)
 92     {
 93         int x = read();int y = read();
 94         add(x,y+n,1);add(y+n,x,0);
 95     }
 96     _for(i,1,n+1)
 97     {
 98         add(0,i,1);add(i,0,0);
 99         add(i+n,2*n+1,1);add(2*n+1,i+n,0);
100     }  
101     int flow = 0;
102     while(bfs()) 
103         while(flow = dinic(s,INF))
104             maxflow += flow;
105     vvis[0] = 1;
106     _for(i,1,n+1)
107     {
108         for(int j = head[i+n]; j ; j = Next[j])
109             if(ver[j]==2*n+1 && val[j]==1)
110                 st.pb(i),vvis[i] = 1; 
111     }
112     
113     vector<int> tmp;
114     _for(i,0,st.size())
115     {
116         vvis[st[i]] = 1,go(st[i],tmp);
117         _for(j,0,tmp.size()-1)
118             printf("%d ",tmp[j]);
119         printf("%d\n",tmp[tmp.size()-1]);
120         tmp.clear();
121     }
122     
123     write(n-maxflow);
124     return 0;
125 }

 

posted @ 2019-10-07 17:47  Asurudo  阅读(181)  评论(0编辑  收藏  举报