題解 Acwing367 學校網路

2022-03-29 21:42:52 字數 3135 閱讀 9188

原題鏈結

顯然,對於圖中任意乙個強連通分量來說,只要將軟體發給其中任意乙個點,就可以到達該強連通分量中的其他所有點。

基於此,我們容易想到先用tarjan演算法求強連通分量,再縮點,從而簡化整張圖,方便我們思考。

縮完點之後這張圖就變成了一張有向無環圖,第一問是求將乙個軟體至少直接發給多少個點,才能使得所有點都收到軟體。

這個問題的答案實際上就是有向無環圖中零入度點的個數(一)。

第二問是求最少需要新增幾條邊,才能使得整張有向無環圖變成一張強連通圖。

這個問題的答案實際上是有向無環圖中零入度點個數與零出度點個數中的較大者(二)。

特別地,如果整張圖本身就是乙個強連通圖,則答案為0。

整個演算法過程很簡單,但是難點在於想出這兩個結論並且想通這兩個結論。下面給出這兩個結論的證明。

(一)的證明:

我們設將軟體提供給ans個點就能使所有點都收到,圖中零入度點個數為p,零出度點個數為q,以下將零入度點稱為「起點」,將零出度點稱為「終點」。

即要證:ans>=p。

(1)對於起點來說,沒有任何一條邊指向它,即沒有任何乙個節點能夠通過某條路徑到達它,故而必須要將軟體發給它。由於一共有p個起點,所以我們至少要將軟體發給這p個起點,故ans>=p。

(2)證明等號成立:

考慮圖中除了起點之外的點。對於其中任意一點,必然可以找到指向它的某一條邊,從而找到它的某個前驅,而後又能通過這個前驅找到其前驅的前驅,以此類推。由於邊數是有限的且圖中無環,故這個找前驅的過程一定會持續到某個點找不到入邊為止,即最終找到乙個起點。那麼通過從這個起點出發的這條路徑便可到達我們所選的這個點。

那麼,除起點外的所有點,必然都可以通過上述方法到達某個起點,

我們設所能達到的所有起點數量為s。首先顯然s不可能超過p,因為一共只有p個起點,故s<=p。

若s然後對於圖中除了這個(些)點之外的點來說,我們只需要將軟體發給s個點,就能到達圖中其他所有節點了。故而我們直接發給的點的個數總和就是p。

若s=p,顯然直接發給這p個節點即可。

故等號成立。

原命題成立。

證畢!上述證明存在漏洞。其只證明了ans>=p且等號成立,但未證明p一定是最小值。

即若存在某個有意義的正整數t=t並且等號成立呢?

也就是說其並未證明ans<=p。

(一)的證明:

我們設答案為ans,圖中零入度點個數為p,零出度點個數為q,以下將零入度點稱為「起點」,將零出度點稱為「終點」。

即要證:ans=p,等價於要證ans>=p且ans<=p。

(1)對於起點來說,沒有任何一條邊指向它,即沒有任何乙個節點能夠通過某條路徑到達它,故而必須要將軟體發給它。由於一共有p個起點,所以我們至少要將軟體發給這p個起點,故ans>=p。

(2)考慮圖中除了起點之外的點。對於其中任意一點,必然可以找到指向它的某一條邊,從而找到它的某個前驅,而後又能通過這個前驅找到其前驅的前驅,以此類推。由於邊數是有限的且圖中無環,故這個找前驅的過程一定會持續到某個點找不到入邊為止,即最終找到乙個起點。那麼通過從這個起點出發的這條路徑便可到達我們所選的這個點。

那麼,除起點外的所有點,必然都可以通過上述方法到達某些起點,且所能到達的所有起點的數量不可能超過p,即ans<=p。

原命題成立。

證畢!

(二)的證明:

不妨p<=q。

(1)考慮p=1的情況。相當於從這乙個起點出發,可以到達所有的終點,那麼我們只需要分別從這q個終點出發向起點加一條邊即可,則總共需要加q條邊。

加完邊之後,對於圖中除起點外的任意乙個點來說,我們必然可以通過不斷找前驅的方式,最終到達起點,同樣也可以通過不斷找後繼的方式,到達某個終點,而這個我們已經從這個終點向起點加了一條邊,則這個終點就可以到達起點。故而這個點與起點和它所能到達的終點共同構成乙個環,故這一部分是強連通的。

由於上面是拿除起點外的任意乙個點來說的,故而整張圖就是一張強連通圖。

(2)考慮p>1的情況,則q>=p>1。

引理:當p>1時,我們必然可以找到兩個起點p1,p2,使得從p1出發能夠到達q1,從p2出發能夠到達q2。

引理的證明:

反證:假設命題不成立,則相當於從所有起點出發,最終只能到達乙個終點。則q故引理成立。

那麼我們加一條從q1出發指向p2的邊,則起點數變為p-1,終點數變為q-1。

只需按此方法加p-1條邊,便可使起點數變為1,即p'=1,此時q'=q-(p-1)。

由(1)可知,當起點數為1時,答案即為終點數。

故總共需要加的邊數ans=q'+(p-1)=q-(p-1)+(p-1)=q。

綜上,答案即為q。

而p>q時同理易證。

證畢!

#include #include #include #include using namespace std;

const int n=110,m=10010;

struct edgeedge[m]; int idx;

int h[n];

int low[n],dfn[n],stk[n],ins[n],id[n];

int timenum,top,scc_cnt;

int din[n],dout[n];

int n;

void init()

void add(int u,int v);h[u]=idx;}

void tarjan(int p)

else if(ins[to])low[p]=min(low[p],dfn[to]);

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

while(p!=y);

}}int main()

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

if(!dfn[i])tarjan(i);

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

for(int i=h[p];~i;i=edge[i].next)

int p=0,q=0;

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

printf("%d\n",p);

if(scc_cnt>1)printf("%d\n",max(p,q));

else puts("0");

return 0;

}

ACwing 天才ACM 題解

題面入口 題目大意,將乙個數列劃分成最少的幾段,滿足每段內的資料集合中,取m對最大最小數出來,將其取出來的每對數求差值並平方,並求這m對的差值平方的求和值s,這個值不能超過指定的t。題目分析 從劃分後的集合中選出m對數,讓每對數的差的平方的和最大值為乙個貪心模型,我們只需要將集合中的元素按從小到大排...

題解 AcWing 1547 約會

原題傳送 acwing 1547.約會 大偵探福爾摩斯接到一張奇怪的字條 我們約會吧!3485djdkxh4hhge 2984akdfkkkkggedsb s hgsfdk d hyscvnm。大偵探很快就明白了,字條上奇怪的亂碼實際上就是約會的時間星期四14 04,因為前面兩字串中第 1 11 對...

題解 AcWing 1519 密碼

原題傳送 acwing 1519.密碼 為了準備pat,系統不得不為使用者生成隨機密碼。但是有時一些數字和字母之間總是難以區分,比如1 數字一 和l l ll 的小寫 0 數字零 和o o oo 的大寫 一種解決辦法是將1 數字一 替換為 將0 數字零 替換為 將l l ll 的小寫 替換為l,將o...