UVALive 7226 Coin Swap

来源:互联网 发布:python 3.2.5.msi下载 编辑:程序博客网 时间:2024/06/10 20:51

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5238

A graph G = (V, E) has a set of V vertices and a set E of edges, and it is connected, that is, there isa path between every pair of vertices in G. Each vertex in has a color which is either black or white.A coin is placed on each vertex in G and each coin also has a black or white color. A pair of adjacentvertices can swap their current coins, which is called a swap operation.

A swap operation is carried out in such a way that one edge in G is selected and the end vertices ofthe edge exchange their coins. Through these swap operations, black coins and white ones should beplaced on black vertices and white ones, respectively, which is the goal of the problem. It is assumedthat the number of black (and white) coins lying on the vertices is equal to the number of the black(and white, resp.,) vertices. That is, we can always achieve the goal of the problem.

Given a graph G, colors of the vertices of G, and colors of coins initially placed on the vertices, yourprogram is to find the minimum number of the swap operations achieving the goal.

For example, in Figure 1, the colors of vertices 1 and 2 are black and the others are white. Thecoins placed on the vertices are drawn as rectangles with their colors. Then after three swap operationsas shown in Figure 1, the colors of coins and vertices agree at each vertex.

这里写图片描述

Figure 1. An example of swap operations.

Input

Your program is to read from standard input. The input consists of T test cases. The number of testcases T is given in the first line of the input. Each test case starts with a line containing two integersn and m (1 ≤ n ≤ 500, −1 ≤ m ≤n(n−1)2), where n and m represent the number of vertices and edges,respectively, of a connected graph G. The vertices are numbered from 1 to n. In each of the followingm lines, there are two integers x and y (1 ≤ x < y ≤ n), which means there is an edge (x, y) connectingthe vertices x and y in G. In the next line, there are n integers ci (ci = 0 or 1, i = 1, . . . , n), separatedby a single space, where ciis the color of the vertex i. In the next line, there are n integers di (di = 0or 1, i = 1, . . . , n), separated by a single space, where diis the color of a coin initially placed on thevertex i. If ci = 0 or di = 0, it means black, and if ci = 1 or di = 1, it means white.

Output

Your program is to write to standard output. Print exactly one line for each test case. The line shouldcontain an integer representing the minimum number of the swap operations such that every vertexshall get a coin of the same color.

The following shows sample input and output for three test cases.

Sample Input

3

4 4

1 2

1 3

2 4

3 4

0 1 1 0

0 1 0 1

6 7

1 2

1 5

1 4

2 3

2 5

4 5

5 6

1 1 0 0 0 0

0 0 0 0 1 1

6 5

1 2

2 3

3 4

4 5

5 6

1 0 1 1 0 0

0 0 1 1 0 1

Sample Output

1

3

5

提示

题意:

在一个图中,每个点有两个状态,状态1中数字1表示黑色圆,0表示白色圆,状态2中数字1表示黑色框,0表示白色框。题目的要求是所有黑色圆与黑色框一一对应的最短距离和是多少?

思路:

用KM套模板。

要最短路,用黑色圆去求离他最近的黑色框是哪一个,求和即可,反过来也可以。

示例程序

#include <stdio.h>#include <string.h>int map[500][500],sp[500],tp[500];struct{    int step,pos;}q[80000];int bfs(int x,int n){    int i,v[500],f=0,top=0;    memset(v,0,sizeof(v));    v[x]=1;    q[top].step=0;    q[top].pos=x;    top++;    while(f<top)    {        x=q[f].pos;        if(tp[x]==1)        {            tp[x]=0;            return q[f].step;        }        for(i=0;n>i;i++)        {            if(v[i]==0&&map[x][i]==1)            {                v[i]=1;                q[top].step=q[f].step+1;                q[top].pos=i;                top++;            }        }        f++;    }}int main(){    int t,i,i1,n,m,u,v,sum;    scanf("%d",&t);    for(i=1;t>=i;i++)    {        memset(map,0,sizeof(map));        sum=0;        scanf("%d %d",&n,&m);        for(i1=1;m>=i1;i1++)        {            scanf("%d %d",&u,&v);            u--;            v--;            map[u][v]=1;//无向图            map[v][u]=1;        }        for(i1=0;n>i1;i1++)        {            scanf("%d",&sp[i1]);//黑色圆做起点        }        for(i1=0;n>i1;i1++)        {            scanf("%d",&tp[i1]);//黑色框做终点        }        for(i1=0;n>i1;i1++)        {            if(sp[i1]==1)            {                sum=sum+bfs(i1,n);            }        }        printf("%d\n",sum);    }    return 0;}
0 0
原创粉丝点击