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

 

你可能感兴趣的:(unix)