hdu 3357 Stock Chase(图论)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3357

分析:本题并不是多么高深的题目,一开始看到题目时以为判断判断图中是否有环,那不是经典的拓扑排序嘛,后来仔细一看这不仅要判断是否有环,而且要数出来会造成环的边,一般的思路是一个一个边的加入,然后判断是否出现环了,如果出现那么条边就不要加入,如果没出现则加入这条边。

增加边时注意这几点:

(1)前提:加入a,b    a->b

(2)当一个节点可以到达a时,那么这个节点也可以到达b

(3)所有b节点能够到达的节点,a节点也能够到达,此时所有能够到达b节点的节点也能够到达b节点所能到达的节点(重点理解)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int mark[250][250];
int N,T;

void add_edge(int a,int b)
{
    mark[a][b]=1;//a可到b
    //1、所有能够到达a点的节点都能够到达b点
    for(int i=1;i<=N;i++)
    if(mark[i][a])mark[i][b]=1;
    //2、所有b点能够到达的点,a节点都能够到达
    for(int i=1;i<=N;i++)
    if(mark[b][i])
    {
          mark[a][i]=1;
          //所有能够到达b点的节点都能够到达b所能够到达的点
          for(int j=1;j<=N;j++)
          if(mark[j][b])mark[j][i]=1;
    }
}

int main()
{
    int a,b,ans,index=0;
    while(scanf("%d%d",&N,&T)!=EOF)
    {
        if(N==0&&T==0)break;
        ans = 0;
        memset(mark,0,sizeof(mark));
        for(int i=0;i<T;i++)
        {
            scanf("%d%d",&a,&b);
            if(mark[b][a]||a==b)ans++;
            else if(mark[a][b]==0)add_edge(a,b);
        }
       // if(ans!=0)
        printf("%d. %d\n",++index,ans);
    }
    return 0;
}

 

原文地址:https://www.cnblogs.com/newpanderking/p/2764074.html