【noip 2015】信息傳遞

去題面的傳送門
QAQ這題有兩種做法

Solution 1: 暴力找環

很明顯題目是讓找最小環,那我們就順着找唄。一開始嘗試用遞歸做,弄了半天也不行,不太好記錄已經跑過了幾個點。
其實每一個點的出度都是1,所以不用存圖,直接一個數組記錄每一個點連接的下一個節點是哪一個就行了。
記得還要for一遍,確定每一個點都跑過。
但是一開始這樣交超時了。
後來發現,其實每次從一個點開始找環的時候,如果直接找到的下一個點是之前訪問過的,直接return就好了

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=200000+10;
int n,ans,tot;
int nxt[maxn],pre[maxn],cnt[maxn];

void done(int x)
{
    int now=x,num=0;
    while(true)
    {
        num++;
        if(pre[now])
        {
            if(pre[now]==x) ans=min(ans,num-cnt[now]);
            break;
        }
        cnt[now]=num;
        if(!pre[now]) tot++;
        pre[now]=x;
        now=nxt[now];
    }
}
int main()
{
    scanf("%d",&n);
    ans=2147483647;
    for(int i=1;i<=n;++i) scanf("%d",&nxt[i]);
    for(int i=1;i<=n;++i)
    {
        if(tot==n) break;
        if(!pre[i]) done(i);
    }
    printf("%d",ans); 
    return 0;
}

Solution 2:tarjan找環

很簡單,打了一遍沒調就過了
直接上代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;

const int maxn=200000+10;
int n,scc_cnt,Index,ans;
int nxt[maxn],scc[maxn],dfn[maxn],low[maxn];
vector<int>incom[maxn];
stack<int>s;

void tarjan(int i)
{
    dfn[i]=low[i]=++Index;
    s.push(i);
    if(!dfn[nxt[i]])
    {
        tarjan(nxt[i]);
        low[i]=min(low[i],low[nxt[i]]);
    }
    else if(!scc[nxt[i]]) low[i]=min(dfn[nxt[i]],low[i]);
    if(low[i]==dfn[i])
    {
        scc_cnt++;
        int j;
        do
        {
            j=s.top();
            s.pop();
            incom[scc_cnt].push_back(j);
            scc[j]=scc_cnt;
        }
        while(i!=j);
    }
}
int main()
{
    scanf("%d",&n);
    ans=2147483647;
    for(int i=1;i<=n;++i) scanf("%d",&nxt[i]);
    for(int i=1;i<=n;++i)
      if(!scc[i]) tarjan(i);
    for(int i=1;i<=scc_cnt;++i)
    {
        int x=incom[i].size();
        if(x>1)
          ans=min(ans,x);
    }
    printf("%d",ans);
    return 0;
} 
發佈了77 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章