UVa 11175:From D to E and back(图论)

来源:互联网 发布:牛牛抢红包软件 编辑:程序博客网 时间:2024/05/22 10:55

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=845&page=show_problem&problem=2116

题意:给一个n个结点的有向图D,可以构造一个图E:D的每条边对应E的一个结点(例如,若D有一条边uv,则E有个结点的名字叫uv),对于D的两条边uv和vw,E中的两个结点uv和vw之间连一条有向边。E中不包含其他边。输入一个m个结点k条边的图E(0m300),判断是否存在对应的图D。E中各个结点的编号为0~m-1。(本段摘自《算法竞赛入门经典(第2版)》)

分析:
       对于D中,a,b,c,d,e五个节点,存在ac,bc,cd,ce四条有向边,如果转换成E图的话,四条有向边会转化成四个结点,同时ac和cd,ac和ce,bc和cd,bc和ce之间会有有向边。则对于E图而言,如果存在i和j结点到k1都有边,而i和j中只有一个结点到k2有边,则这个图是不可能转化来的。因此暴力枚举i,j和k判断是否可行即可。

代码:

#include <iostream>#include <algorithm>#include <fstream>#include <cstring>#include <vector>#include <queue>#include <cmath>#include <stack>using namespace std;const int maxn = 300 + 5;int T, n, m, x, y;int a[maxn][maxn];bool judge(){    for (int i = 0; i < n; ++i)        for (int j = 0; j < n; ++j)        {            bool f1 = false, f2 = false;            for (int k = 0; k < n; ++k)            {                if (a[i][k] && a[j][k])                    f1 = true;                if (a[i][k] ^ a[j][k])                    f2 = true;            }            if (f1 && f2)                return false;        }    return true;}int main(){    scanf("%d", &T);    for (int C = 0; C < T; ++C)    {        memset(a, 0, sizeof(a));        scanf("%d%d", &n, &m);        for (int i = 0; i < m; ++i)        {            scanf("%d%d", &x, &y);            a[x][y] = 1;        }        printf("Case #%d: ", C + 1);        if (judge())            printf("Yes\n");        else            printf("No\n");    }    return 0;}
0 0
原创粉丝点击