uva753(最大流)

题目的意思就是有n种插口,然后有m个设备,每个设备可以插一种插口,然后有k种(注意是种,个数不限)转换器,可以把一种设备的插口转成另一种.

现在问有几个设备充不上电.,


首先用一个超级源点 把插口都连到超级源点,容量为1.

然后把所有设备都连到超级汇点.

然后通过转化器构造中间的边,容量是INF.

在ek模板算法就能算出最大流..


#include
#include
#include
using namespace std;
const int N = 500;
const int INF = 0x3f3f3f3f;
int cap[N][N];
int flow[N][N];
char str[N][25];
char temp[25];
char temp2[25];
int p[N];
int a[N];
int sum;
int num;
int n,m,k,f;
int search(char *c) {
	for (int i = 1 ; i < sum ;i++) {
		if(strcmp(c , str[i]) == 0)
			return i;
	}
	strcpy(str[sum] , c);
	return sum++;
}
int ek(int t) {  
    queue q;  
    memset(flow , 0 ,sizeof(flow));  
    f = 0;  
    while(1) {  
        memset(a, 0 ,sizeof(a));  
        a[0] = INF;  
        q.push(0);  
        while(!q.empty()) {  
            int u = q.front() ;  
            q.pop();  
            for (int v = 0 ; v <= t; v++) { 
                if (!a[v] && cap[u][v] - flow[u][v] > 0) {
                    p[v] = u ;
                    q.push(v);
                    a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v];  
                }  
            }  
        }  
        if (a[t] == 0)  
            break;  
        for (int u = t ; u != 0 ;u = p[u]) {  
            flow[p[u]][u] += a[t];  
            flow[u][p[u]] -= a[t];  
        }  
        f += a[t];  
    }  
    return m - f;  
}  
int main () {
	int t;
	scanf("%d",&t);
	while(t--) {
		sum = 1;
		memset(cap , 0 ,sizeof(cap));
		scanf("%d",&n);
		for (int i = 1 ; i <= n ;i++) {
			scanf("%s",temp);
			cap[0][search(temp)] += 1;
		}
		scanf("%d",&m);
		for (int i = 1 ; i <= m ;i++) {
			scanf("%s",temp);
			scanf("%s",temp);
			p[i] = search(temp);
		}
		scanf("%d",&k);
		for (int i = 0 ; i < k ;i++) {
			scanf("%s",temp);
			scanf("%s",temp2);
			int u = search(temp);
			int v = search(temp2);
			cap[v][u] = INF;
		}
		for (int i = 1 ; i <= m ;i++) {
			cap[p[i]][sum] += 1;
		}
		int res = ek(sum);
		printf("%d\n",res);
		if(t)
			printf("\n");
	}
}


你可能感兴趣的:(图论,uva)