A Plug for UNIX--POJ 1087
1、题目类型:图论、最大流、Edmonds_Karp算法。
2、解题思路:(1)对输入的receptacle、devices的类型和数目进行构图,注意重边增加边的权值加加即可,而对于adapter的权值是无穷大;(2)Edmonds_Karp算法获得此时图的最大流,结果为devices总数减去最大流量max即可。
3、注意事项:注意receptacle、devices的数目是一定的几位n、m,而adapter是无限的;图的节点数开到600才可,否则RE。
4、实现方法:
#pragma warning(disable:4786)
#include<iostream>
#include<map>
#include<algorithm>
#include<string>
using namespace std;
#define inf 10000000
#define MAXN 600
int n,m,k,s,t;
map<string,int> M1;
map<int,int> M2;
int gra[600][600];
int r[MAXN][MAXN];
int pre[MAXN],d[MAXN];
void Init()
{
int i,cnt=1;
string str,Ts1,Ts2;
map<int,int>::iterator it;
cin>>n;
for(i=0;i<n;i++)
{
cin>>str;
if(!M1[str])
{
M1[str]=cnt++;
M2[M1[str]]=1;
}
else
M2[M1[str]]++;
}
cin>>m;
s=0;
int pos=1;
for(i=0;i<m;i++)
{
cin>>Ts1>>Ts2;
gra[s][pos]=1;
if(M1[Ts2])
{
gra[pos][M1[Ts2]+m]=1;
}
else
{
M1[Ts2]=cnt++;
gra[pos][M1[Ts2]+m]=1;
}
pos++;
}
cin>>k;
for(i=0;i<k;i++)
{
cin>>Ts1>>Ts2;
if(!M1[Ts1])
M1[Ts1]=cnt++;
if(!M1[Ts2])
M1[Ts2]=cnt++;
gra[M1[Ts1]+m][M1[Ts2]+m]=inf;
}
t=m+M1.size()+1;
for(it=M2.begin();it!=M2.end();it++)
{
gra[it->first+m][t]=it->second;
}
}
bool BFS(int s, int t, int n)
{
//以下求最短路径增广
int front, rear, u, v;
int Q[MAXN * MAXN];
memset(pre, -1, sizeof(pre));
front = rear = 0;
Q[rear++] = s;
d[s] = 0;
while (front < rear)
{
u = Q[front++];
for (v = 0; v < n; v++)
{
if (pre[v] == -1 && r[u][v] > 0)
{
pre[v] = u;
d[u] = d[v] + 1;
Q[rear++] = v;
if(v == t) return true;
}
}
}
return false;
}
int Edmonds_Karp(int s, int t, int n)
{
int u, v, inc, maxflow = 0;
while (true)
{
//终点不在剩余网络中
if (!BFS(s, t, n))
break;
inc = 10000000;
//以下求增广的流量
for (v = t; v != s; v = u)
{
u = pre[v];
if(r[u][v] < inc) inc = r[u][v];
}
//以下重建剩余网络
for(v = t; v != s; v = u)
{
u = pre[v];
r[u][v] -= inc;
r[v][u] += inc;
}
maxflow += inc;//增加流量
}
return maxflow;
}
int main()
{
Init();
memcpy(r,gra,sizeof(gra));
int tmp=Edmonds_Karp(s,t,t+1);
if(m-tmp>=0)
cout<<m-tmp<<endl;
return 0;
}