《洛谷2661 資訊傳遞 》

2022-06-19 20:15:09 字數 1375 閱讀 6183

看到題目後,顯然是求乙個最小的環。(把每個人看成點,關係看成邊。)

但是這裡可以對題目做乙個轉化。

可以發現每個人的只能有乙個目標點。

對於環上的點,顯然這個環上的任意乙個點都不會再往外走。那麼只存在別的點連入該環的情況。

別的點連入該環後,別的點顯然無法再成環。

那麼,我們可以將這些點都刪去,最後只留下所有的環。

如何刪點?首先可以發現,對於不成環的點,肯定存在乙個點入度為0.

那麼將這個入度為0的點刪去,然後將這個點的目標點的入度也-1。

注意的是,可能我們在刪去乙個點後,前面的點也變成入度為0了,所以在每次刪點後,判斷目標點也也是否需要刪去。

然後刪過的點就不要刪了,打上標記。

注意這樣處理後,如果去遍歷環上的所有點,複雜度還是o(n^2),會t。

但是我們可以發現,對於環上的任意一點,他們的完成時間都是一樣的。

那麼我們在遍歷乙個環時,將環上的所有點都打上標記,乙個環只遍歷一次。

複雜度就降到了o(n)左右。

code:

#includeusing

namespace

std;

typedef

long

long

ll;typedef pair

pii;

const

int n = 2e5+5

;const

int m = 4005*4005

;#define pi acos(-1)

#define inf 1e8

#define inm int_min

#define dbg(ax) cout << "now this num is " << ax << endl;inline

intread()

while(c >= '

0' && c <= '9')

return x*f;

}int to[n],in[n],vis[n],ans =inf;

void delete(int

x)void dfs(int x,int rt,int

sum)

dfs(to[x],rt,sum+1);}

intmain()

for(int i = 1;i <= n;++i) if(in[i] == 0 && !vis[i]) delete(i);

for(int i = 1;i <= n;++i) if(in[i] != 0 && !vis[i]) dfs(i,i,0

); printf(

"%d\n

",ans);

system(

"pause");

return0;

}

view code

洛谷2661 資訊傳遞

題目描述 有n個同學 編號為1到n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取資...

洛谷P2661 資訊傳遞

有n個同學 編號為1到n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取資訊,但是每...

洛谷 P2661 資訊傳遞

有 n個同學 編號為1到 n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為 i的同學的資訊傳遞物件是編號為 ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取資訊...