洛谷P1262 間諜網路

2022-05-26 03:36:12 字數 1755 閱讀 3068

給定n個點 其中p個點可以被賄賂, 被賄賂的金額為x,如果乙個點被賄賂,他所指向的點也會被賄賂

求:如果不能全部被賄賂 輸出no以及不能被賄賂的點 否則輸出yes和需要支付的金額的最小值

我們可以通過tarjan縮點,最後掃一遍dfn,若果有乙個點並沒有被訪問過,說明這個點肯定不會被賄賂 直接輸出並結束程式

那麼如果全部可以賄賂呢?我們想,乙個強聯通分量裡面隨便賄賂乙個點,其他的全部都會被賄賂 那麼我們是不是只在需要在進行tarjan的時候進行比較,求出最小值即可

然而 如果乙個強聯通分量指向另乙個強聯通分量,我們就可以用指向另乙個的強聯通分量裡的最小值就可以了

有同學問:如果被指向的強聯通分量裡面有乙個比指向的最小值還小的值,是不是可以用呢?

答案是不可以的 如果選擇了指向的強聯通分量,我們的花費是x,此時因為他指向另乙個強聯通分量,所以另乙個不需要花錢,所以我們只需要統計入度為0的強聯通分量,並且累加答案就可以了

注意:在進行tarjan的時候while(stack[top]! = u)前面後面都要有乙個更新答案 因為有2中種特殊情況:u在棧頂和棧尾,當然你也可以不這麼寫,直接將top+1即可while(stack[top + 1] != u)

#include const

int inf = 1e9 + 10

;using

namespace

std;

intn, p, r, num, top, col, sh;

int mon[3010], coin[3010], head[10010], dfn[3010

];int st[3010], co[3010], low[3010], si[3010], vis[3010

];int ans[3010], ru[3010

];struct

emmm e[

10010

];void tarjan(int

u)

else

if (!co[v])

low[u] =min(low[u], dfn[v]);

}if (dfn[u] ==low[u])

ans[col] =min(ans[col], mon[st[top]]);

top--;

}return;}

void add(int

from, int

to)

intmain()

cin >>r;

for (int i = 1;i <= r; i++)

for (int i = 1;i <= n; i++)

if (!dfn[i] && mon[i] !=inf)

tarjan(i);

for (int i = 1;i <= n; i++)

if (!dfn[i])

for (int i = 1;i <= n; i++)

for (int j = head[i]; j; j =e[j].next)

if (co[i] !=co[e[j].to])

ru[co[e[j].to]]++;

int anss = 0

;

for (int i = 1;i <= col; i++)

if (!ru[i])

anss+=ans[i];

cout

<< "

yes"

<< endl << anss <

return0;

}

ac code

洛谷 P1262 間諜網路

題目描述 由於外國間諜的大量滲入,正處於高度的危機之中。如果a間諜手中掌握著關於b間諜的犯罪證據,則稱a可以揭發b。有些間諜收 賂,只要給他們一定數量的美元,他們就願意交出手中掌握的全部情報。所以,如果我們能夠收買一些間諜的話,我們就可能控制間諜網中的每一分子。因為一旦我們逮捕了乙個間諜,他手中掌握...

洛谷 P1262 間諜網路

題目描述 由於外國間諜的大量滲入,正處於高度的危機之中。如果a間諜手中掌握著關於b間諜的犯罪證據,則稱a可以揭發b。有些間諜收 賂,只要給他們一定數量的美元,他們就願意交出手中掌握的全部情報。所以,如果我們能夠收買一些間諜的話,我們就可能控制間諜網中的每一分子。因為一旦我們逮捕了乙個間諜,他手中掌握...

P1262 間諜網路

傳送門 顯然可以把所有間諜的關係建乙個圖 如果a間諜手中掌握著關於b間諜的犯罪證據,那就從a連一條邊到b 如果賄賂了乙個間諜,那麼整個聯通塊的間諜肯定都被控制 那就先把圖縮成dag 如果控制了乙個塊,那麼這個塊後面所有的塊都能被控制 為了控制所有塊,一定要賄賂沒有入度的塊,因為它不能被其它塊控制到 ...