HDU 4324 Triangle LOVE(拓扑排序)

HDU 4324 Triangle LOVE(拓扑排序)

http://acm.hdu.edu.cn/showproblem.php?pid=4324

题意:

        给你一个特殊的有向图,该有向图的任意两个节点u与v之间有且仅有一条单向边,现在问你该有向图是否存在由3个节点构成的环。

分析:

       该图本质是拓扑排序题.如果该图可以拓扑排序,那么不存在3节点的环,否则存在3节点的环.下面是证明:

       首先存在3节点的环-> 不能拓扑排序.

       其次我们现在证明 不能拓扑排序->存在3节点的环.

假设图不能拓扑排序,那么该图一定存在一个n节点(n>=3)的环.假设该环为a->b->c->d->….. 等. 由于a与c之间必然存在边,所以如果此边为c->a,那么就存在3节点环了.否则此边为a->c的话,那么a->c->d->…构成了一个n-1节点的环.依次类推,我们可以有n节点的环得出该图必然存在n-1,n-2,…一直到3节点的环.

       所以能拓扑排序 <==>不存在3节点环.

AC代码: (读输入的时候,如果一次读一个字符会超时)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=2000+10;
int n;
vector<int> G[maxn];
int in[maxn];
bool topo()
{
    queue<int> Q;
    for(int i=0;i<n;i++)
        if(!in[i]) Q.push(i);
    int sum=0;
    while(!Q.empty())
    {
        int u=Q.front(); Q.pop();
        sum++;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(--in[v]==0) Q.push(v);
        }
    }
    return sum==n;
}
int main()
{
    int T; scanf("%d",&T);
    for(int kase=1;kase<=T;kase++)
    {
        scanf("%d",&n);
        memset(in,0,sizeof(in));
        for(int i=0;i<n;i++)
        {
            G[i].clear();
            char str[maxn];
            scanf("%s",str);
            for(int j=0;j<n;j++)if(str[j]=='1')
            {
                G[i].push_back(j);
                in[j]++;
            }
        }
        printf("Case #%d: %s\n",kase,topo()?"No":"Yes");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值