Plug It In!(网络流板子)
Posted sylvia1111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Plug It In!(网络流板子)相关的知识,希望对你有一定的参考价值。
问题 E: Plug It In!
时间限制: 12 Sec 内存限制: 128 MB题目描述
Adam just moved into his new apartment and simply placed everything into it at random. This means in particular that he did not put any effort into placing his electronics in a way that each one can have its own electric socket.
Since the cables of his devices have limited reach, not every device can be plugged into every socket without moving it first. As he wants to use as many electronic devices as possible right away without moving stuff around, he now tries to figure out which device to plug into which socket. Luckily the previous owner left behind a plugbar which turns one electric socket into 3.
Can you help Adam figure out how many devices he can power in total?
Since the cables of his devices have limited reach, not every device can be plugged into every socket without moving it first. As he wants to use as many electronic devices as possible right away without moving stuff around, he now tries to figure out which device to plug into which socket. Luckily the previous owner left behind a plugbar which turns one electric socket into 3.
Can you help Adam figure out how many devices he can power in total?
输入
The input consists of:
• one line containing three integers m, n and k, where
– m (1 ≤ m ≤ 1 500) is the number of sockets;
– n (1 ≤ n ≤ 1 500) is the number of electronic devices;
– k (0 ≤ k ≤ 75 000) is the number of possible connections from devices to sockets.
• k lines each containing two integers xi and yi indicating that socket xi can be used to power device yi .
Sockets as well as electronic devices are numbered starting from 1.
The plugbar has no cable, i.e. if it is plugged into a socket it simply triples it.
• one line containing three integers m, n and k, where
– m (1 ≤ m ≤ 1 500) is the number of sockets;
– n (1 ≤ n ≤ 1 500) is the number of electronic devices;
– k (0 ≤ k ≤ 75 000) is the number of possible connections from devices to sockets.
• k lines each containing two integers xi and yi indicating that socket xi can be used to power device yi .
Sockets as well as electronic devices are numbered starting from 1.
The plugbar has no cable, i.e. if it is plugged into a socket it simply triples it.
输出
Output one line containing the total number of electrical devices Adam can power.
样例输入
3 6 8
1 1
1 2
1 3
2 3
2 4
3 4
3 5
3 6
样例输出
5
题意 n个插头,m条电线,有一个 一转三的插座,输出最大可连的设备数;
二分图匹配题;最大匹配数=网络流的最大流;但是一转三的插头,应该通过枚举加一条S到插头点的边,由于图跑一边网络流,就不能再用了,所以要先存起来;
1 #include<bits/stdc++.h> 2 #define INF LLONG_MAX/2 3 #define N 80500 4 using namespace std; 5 6 struct ss 7 8 int v,next; 9 long long flow; 10 ; 11 int head[N],now_edge=0,S,T; 12 ss edg[N*10]; 13 14 ss lsedg[N*10]; 15 int lshead[N],lssum_edge; 16 void init() //初始化 17 18 now_edge=0; 19 memset(head,-1,sizeof(head)); 20 21 22 void addedge(int u,int v,long long flow) //加边,加双向边,反向边为0 23 24 edg[now_edge]=(ss) 25 26 v,head[u],flow 27 ; 28 head[u]=now_edge++; 29 edg[now_edge]=(ss) 30 31 u,head[v],0 32 ; 33 head[v]=now_edge++; 34 35 36 int dis[N]; 37 38 int bfs() //这个过程给网络分层,避免循环跑; 39 40 memset(dis,0,sizeof(dis)); 41 queue<int>q; 42 q.push(S); 43 dis[S]=1; 44 45 while(!q.empty()) 46 47 int now=q.front(); 48 q.pop(); 49 50 for(int i=head[now]; i!=-1; i=edg[i].next) 51 52 ss &e=edg[i]; 53 if(e.flow>0&&dis[e.v]==0) 54 55 dis[e.v]=dis[now]+1; 56 q.push(e.v); 57 58 59 60 61 if(dis[T]==0)return 0; 62 return 1; 63 64 65 int current[N];//就是记录了当前搜索到了这个点的哪一条边 66 long long dfs(int x,long long maxflow) 67 68 if(x==T)return maxflow; 69 for(int i=current[x]; i!=-1; i=edg[i].next) 70 71 current[x]=i;//然后接下来直接从这个边搜索就行了 72 73 ss &e=edg[i]; 74 if(e.flow>0&&dis[e.v]==dis[x]+1) //流量大于0,且在下一层 75 76 long long flow=dfs(e.v,min(maxflow,e.flow)); //在最大流和当前流取较小值 77 78 if(flow!=0) 79 80 e.flow-=flow; 81 edg[i^1].flow+=flow; 82 return flow; 83 84 85 86 return 0; 87 88 89 long long dinic() 90 91 long long ans=0,flow; 92 93 while(bfs()) 94 95 for(int i=0; i<N; i++)current[i]=head[i]; 96 while(flow=dfs(S,INF))ans+=flow; 97 98 return ans; 99 100 //以上都是板子,用于求最大流 101 //二分图匹配问题,二分图的每条边权值都是1,二分图最大匹配就是最大流 102 int main() 103 104 int m,n,k; 105 long long res=0; 106 scanf("%d%d%d",&m,&n,&k); 107 init(); 108 S=n+m+1,T=S+1; 109 for(int i=0; i<k; i++) 110 111 int u,v; 112 scanf("%d %d",&u,&v); 113 addedge(u,v+m,1); //把u,v都变成不重复的数值 114 115 for(int i=1; i<=m; i++) 116 117 addedge(S,i,1); //把起点与二分图的一半连起来 118 119 for(int i=1; i<=n; i++) 120 121 addedge(i+m,T,1); //与终点连起来 122 123 long long nowmax=dinic(); //跑一边最大流 124 long long cancan=0; 125 126 for(int i=0; i<now_edge; i++) //将图存起来 127 128 lsedg[i].flow=edg[i].flow; 129 lsedg[i].next=edg[i].next; 130 lsedg[i].v=edg[i].v; 131 132 for(int i=0;i<=n+m+2;i++)lshead[i]=head[i]; 133 lssum_edge=now_edge; 134 135 for(int i=1; i<=m; i++) //然后手动把图复制,枚举起点到二分图的点,且权值为2 136 137 now_edge=lssum_edge; 138 for(int i=0; i<now_edge; i++) 139 140 edg[i].flow=lsedg[i].flow; 141 edg[i].next=lsedg[i].next; 142 edg[i].v=lsedg[i].v; 143 144 for(int i=0;i<=n+m+2;i++)head[i]=lshead[i]; 145 146 addedge(S,i,2); 147 long long dangqiancancan=dinic(); 148 149 cancan=max(cancan,dangqiancancan);//维护一个最大值 150 151 printf("%lld\n",cancan+nowmax); 152 153 return 0; 154
以上是关于Plug It In!(网络流板子)的主要内容,如果未能解决你的问题,请参考以下文章
C - A Plug for UNIX POJ - 1087 网络流