Luogu P1262 間諜網路

2022-05-05 12:03:09 字數 2880 閱讀 3640

pre芝士\(of\)

\(tarjan\),下方也有引用的:\(\text\)

題目給了你乙個有向圖,乙個有環,而且只有部分點有點權,部分點沒有的乙個有向圖。你現在使用點\(n\)點權值大小的代價可以進行:將這個點以及這個點可以到達的所有點放入點集\(\mathbf e\)中的操作,保證在點集\(\mathbf e\)中的所有點能到達的點也都在\(\mathbf e\)。

如果\[a \rightarrow b

\]\[a \in \mathbf e

\]則保證

\[b \in \mathbf e

\]那麼問將所有點放入點集\(\mathbf e\)的最小代價是多少。如果不能輸出\(\text\)以及無法放入的點中最小的那個,可以則輸出\(\text\) & 最小代價。

我們先對題目細節進行分析:

首先是有向圖

如果\(a\)可以購買,\(a\)可以到\(b\),那麼花費\(value_a\)可以使得\(\left\ \subseteq \mathbf e\),可是不保證買下\(b\)就有\(a\)或者說b可能根本無法單獨獲取。

那麼很顯然我們不能點對點分析了,這樣不能保證獲得最小代價也不能保證複雜度優秀。

既然不能點對點分析,我們就考慮對於這題圖的特性。

首先我會想到跑類似點權最短路的東西,但是似乎無法實現,因為如果存在不可到達的點,並不能很好判斷,而且在跑最短路時我們如果將沒有點權的點貪心為0,那麼無法繼續程式。稍微改下思路,這樣反而變成乙個裸的dfs,複雜度與實現難度變得奇奇怪怪。

不過既然想到所謂點權最短路,那麼我們就可以考慮到,對於點權最短路,我們必須考慮是否\(\text\),不是\(\text\)就不能完美實現記憶化搜尋等點權計算的操作。畢竟點不是有向邊,對於點來說很可能會陷入死迴圈。

結合以上資訊,我們突然想到乙個模板涵蓋以上特點:p3387 【模板】縮點。

還沒學\(tarjan\)的同學,歡迎來踩\(\text\)

如果我們對這題進行縮點,大部分問題就迎刃而解。

對於這個題,縮點後的處理才是更為精髓的部分。

我寫這篇題解其實是因為對於我自己的做法,我很吃驚居然ac了,先縮點,縮點時記得記錄這個強連通分量內最便宜的那個,如果沒有能買的也要記錄一下「-1」為不能買的。

我在縮完點後,乾脆對每乙個點做dfs,能走的點盡量走,dfs時順便記憶化該點是否走過,如果走過則不再dfs。就直接從第乙個點開始列舉,判斷2點:1是是否有能購買的,沒有你dfs也沒用,有的話還要看之前的點是否涵蓋他了。

這個很離譜對吧,真的很離譜,因為他是錯的,他只有\(92pts\)

(就這還92啊)

對於這種情況,很明顯只需要買2就只需\(val=4\)一石二鳥,但我for迴圈從1開始dfs我就會先買1在買2導致\(val=7\)。

然後我想了想。。。想了想。我想到可以換每個點都做一次起點,但那樣貌似t了。

然後我常識性地把他倒著迴圈了一遍然後再做,取最小的那個。

就a了。所以就驚了並且摸了(指不再深究)。

\(\text\)的情況詳見**。

#include#include#include#include#include#include#include#define n 300005

using namespace std;

int n,p,r;

int val[n],dfn[n],low[n],tot,cnt,sec[n],secs,size[n],head[n],rtsec[n],head1[n],x[n],y[n];

int ans;

stack s;

bool in[n],oksec[n];

struct rey

e[1000005],e1[1000005];

void add(int u,int v)

void add1(int u,int v)

void tarjan(int x)

else if(in[go])low[x]=min(low[x],dfn[go]);

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

while(x!=tp);

}}//tarjan縮點模板,詳見另一篇學習筆記。

void dfs(int u)

}//dfs一直走並記錄走過的。

int main()

scanf("%d",&r);

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

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

cnt=0;

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

//縮點完也要重新建圖,因為縮點後雖然沒有環或者強聯通分量,

//但是存在買整個強連通分量同時獲得另乙個的情況。

} for(int i=1;i<=secs;i++)

//dfs

} bool ok=1;

int outw=n+1;

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

//仍然沒走的就一定是no

for(int j=1;j<=n;j++)}}

} if(ok==0)

int tmp=ans;

ans=0;

memset(oksec,0,sizeof(oksec));

for(int i=secs;i>=1;i--)

}//倒著來一遍

ans=min(ans,tmp);

printf("yes\n%d\n",ans);

return 0;

}

可能是資料比較水,如果有大佬可以hack掉我會很感激並優化題解和**。

P1262 間諜網路

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

洛谷 P1262 間諜網路

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

洛谷 P1262 間諜網路

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