程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> POJ 2762 Going from u to v or from v to u?(強連通分量+拓撲排序)

POJ 2762 Going from u to v or from v to u?(強連通分量+拓撲排序)

編輯:關於C++

題目地址:POJ 2762
先縮點,然後判斷拓撲網絡每層的個數是否為1(我承認如果事先不知道這題需要拓撲排序我是想不出來這點的。。。)。因為假如有一層為2的話,那麼從此之後這兩個岔路的點就不可能從一點到另一點的。
代碼如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=1000+10;
int head[MAXN], Ecnt, scc, top, indx;
int low[MAXN], dfn[MAXN], belong[MAXN], stk[MAXN], instack[MAXN];
struct node
{
        int u, v, next;
}edge[7000];
void add(int u, int v)
{
        edge[Ecnt].v=v;
        edge[Ecnt].next=head[u];
        head[u]=Ecnt++;
}
void tarjan(int u)
{
        low[u]=dfn[u]=++indx;
        instack[u]=1;
        stk[++top]=u;
        for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u]=min(low[u],low[v]);
                }
                else if(instack[v]){
                        low[u]=min(low[u],dfn[v]);
                }
        }
        if(low[u]==dfn[u]){
                scc++;
                while(1){
                        int v=stk[top--];
                        belong[v]=scc;
                        instack[v]=0;
                        if(u==v) break;
                }
        }
}
void init()
{
        memset(head,-1,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(instack,0,sizeof(instack));
        Ecnt=top=indx=scc=0;
}
int head1[MAXN], Ecnt1, deg[MAXN];
struct node1
{
        int u, v, next;
}edge1[7000];
void add1(int u, int v)
{
        edge1[Ecnt1].v=v;
        edge1[Ecnt1].next=head1[u];
        head1[u]=Ecnt1++;
}
bool topo(int scc)
{
        int i, u, tot, m=scc;
        while(m--){
                tot=0;
                for(i=1;i<=scc;i++){
                        if(!deg[i]){
                                tot++;
                                u=i;
                                deg[i]--;
                        }
                }
                if(tot>1) return false;
                for(i=head1[u];i!=-1;i=edge1[i].next){
                        deg[edge1[i].v]--;
                }
        }
        return true;
}
void init1()
{
        memset(deg,0,sizeof(deg));
        memset(head1,-1,sizeof(head1));
        Ecnt1=0;
}
int main()
{
        int n, m, i, j, u, v, t, f;
        scanf("%d",&t);
        while(t--){
                scanf("%d%d",&n,&m);
                init();
                while(m--){
                        scanf("%d%d",&u,&v);
                        add(u,v);
                }
                for(i=1;i<=n;i++){
                        if(!dfn[i])
                                tarjan(i);
                }
                init1();
                for(i=1;i<=n;i++){
                        for(j=head[i];j!=-1;j=edge[j].next){
                                v=edge[j].v;
                                if(belong[i]!=belong[v]){
                                        add1(belong[i],belong[v]);
                                        deg[belong[v]]++;
                                        //printf("%d %d\n",belong[i],belong[v]);
                                }
                        }
                }
                if(topo(scc)) puts("Yes");
                else puts("No");
        }
        return 0;
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved