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;
}

 

posted @ 2010-09-25 21:53  勇泽  阅读(325)  评论(0编辑  收藏  举报