[網絡流24題] 最小路徑覆蓋問題 (最大流/匈牙利 二分圖匹配)

洛谷傳送門 LOJ傳送門html

部落戰爭這道題差很少api

讓咱們求一個有向圖中的全部點,最少被多少條不相交的鏈覆蓋,並輸出方案網絡

鏈除了兩頭,中間的點出度入度都是$1$。spa

咱們把鏈壓成彈簧形,問題轉化成了二分圖匹配?code

全部找不到匹配的位置都是鏈頭!htm

而匈牙利的時間複雜度十分不友好,那麼怎麼用網絡流作呢?blog

因爲是有向圖,因此咱們要把每一個點都拆成入點和出點,來起到有向邊的做用get

源點$S$向入點連流量爲$1$的邊,每一個出點向匯點$T$連流量爲$1$的邊string

圖中的每條邊,都從入點連向對應標號的出點,流量爲$1$it

在跑完最大流以後,若是某個點不是鏈尾,它入點的流量必定爲$1$,由於在鏈中它後面還有點,不然它就是鏈尾

輸出方案,從新建圖,$dfs$一遍就好了

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 350
 6 #define M1 20010
 7 #define ll long long
 8 #define dd double
 9 #define inf 0x3f3f3f3f
 10 using namespace std;  11 
 12 int gint()  13 {  14     int ret=0,fh=1;char c=getchar();  15     
 16     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}  17     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}  18     return ret*fh;  19 }  20 
 21 int n,m,nm,S,T;  22 struct Edge{  23 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cte;  24 void ae(int u,int v,int F)  25 {  26     cte++; to[cte]=v; flow[cte]=F;  27     nxt[cte]=head[u]; head[u]=cte;  28 }  29 }e,g;  30 
 31 int que[M1*2],hd,tl,cur[N1],dep[N1],inc[N1],ouc[N1];  32 int bfs()  33 {  34     int x,j,v;  35     memset(dep,-1,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));  36     hd=1,tl=0; que[++tl]=S; dep[S]=0;  37     while(hd<=tl)  38  {  39         x=que[hd++];  40         for(j=e.head[x];j;j=e.nxt[j])  41  {  42             v=e.to[j]; if(!e.flow[j]||dep[v]!=-1) continue;  43             dep[v]=dep[x]+1; que[++tl]=v;  44  }  45  }  46     return dep[T]!=-1;  47 }  48 int dfs(int x,int limit)  49 {  50     int j,v,flow,ans=0; if(x==T||!limit) return limit;  51     for(j=cur[x];j;j=e.nxt[j])  52  {  53         cur[x]=j; v=e.to[j];  54         if( dep[v]==dep[x]+1 && (flow=dfs(v,min(limit,e.flow[j]))) )  55  {  56             limit-=flow, ans+=flow;  57             e.flow[j]-=flow, e.flow[j^1]+=flow;  58             if(!limit) break;  59  }  60  }  61     return ans;  62 }  63 void dfs_ans(int x)  64 {  65     int j,v;  66     if(x!=S) printf("%d ",x);  67     for(j=g.head[x];j;j=g.nxt[j])  68  {  69         v=g.to[j];  70  dfs_ans(v);  71         if(x==S) puts("");  72  }  73 }  74 int Dinic()  75 {  76     int mxflow=0,x,j,v,i;  77     while(bfs())  78  {  79         mxflow+=dfs(S,inf);  80  }  81     for(x=1;x<=n;x++)  82         for(j=e.head[x];j;j=e.nxt[j])  83  {  84             v=e.to[j];  85             if(v<=n||v>n+n||e.flow[j]) continue;  86             g.ae(x,v-n,0); inc[v-n]++; //ouc[x]++;
 87  }  88     for(i=1;i<=n;i++) if(!inc[i]) g.ae(S,i,0); //ouc[S]++;
 89  dfs_ans(S);  90     return mxflow;  91 }  92 
 93 
 94 int main()  95 {  96     scanf("%d%d",&n,&m);  97     int i,j,x,y,ans; S=n+n+1,T=n+n+2; e.cte=1;  98     for(i=1;i<=n;i++) e.ae(S,i,1), e.ae(i,S,0), e.ae(i+n,T,1), e.ae(T,i+n,0);  99     for(i=1;i<=m;i++) x=gint(), y=gint(), e.ae(x,y+n,1), e.ae(y+n,x,0); 100     printf("%d\n",n-Dinic()); 101     return 0; 102 }
相關文章
相關標籤/搜索