標籤:void 完成 cst vector 輸入輸出 algo 格式 ack 網路
題目描述
一些學校連入一個電腦網路。那些學校已訂立了協議:每個學校都會給其它的一些學校分發軟體(稱作“接受學校”)。注意即使 B 在 A 學校的分發列表中, A 也不一定在 B 學校的列表中。
你要寫一個程式計算,根據協議,為了讓網路中所有的學校都用上新軟體,必須接受新軟體副本的最少學校數目(子任務 A)。更進一步,我們想要確定通過給任意一個學校發送新軟體,這個軟體就會分發到網路中的所有學校。為了完成這個任務,我們可能必須擴充接收學校列表,使其加入新成員。計算最少需要增加幾個擴充,使得不論我們給哪個學校發送新軟體,它都會到達其餘所有的學校(子任務 B)。一個擴充就是在一個學校的接收學校列表中引入一個新成員。
輸入輸出格式
輸入格式:
輸入檔案的第一行包括一個整數 N:網路中的學校數目(2 <= N <= 100)。學校用前 N 個正整數標識。
接下來 N 行中每行都表示一個接收學校列表(分發列表)。第 i+1 行包括學校 i 的接收學校的標識符。每個列表用 0 結束。空列表只用一個 0 表示。
輸出格式:
你的程式應該在輸出檔案中輸出兩行。
第一行應該包括一個正整數:子任務 A 的解。
第二行應該包括子任務 B 的解。
輸入輸出範例輸入範例#1:
52 4 3 04 5 0001 0
輸出範例#1:
12
說明
題目翻譯來自NOCOW。
USACO Training Section 5.3
#include<cstdio>#include<stack>#include<algorithm>#include<vector>#define maxn 10001using namespace std;int n,m,low[maxn],dfn[maxn],sccno[maxn],dep,scc,in[maxn],out[maxn],inc,outc;stack<int> s;//用棧可有效防止原圖被破壞 vector<int> g[maxn];void t(int u){dfn[u]=low[u]=++dep;//-- s.push(u);//u入隊 for(int i=0;i<g[u].size();++i){ int v=g[u][i]; if(!dfn[v])t(v),low[u]=min(low[u],low[v]);//如果 沒有訪問過v就將v targan並 更新low[u] else if(!sccno[v])low[u]=min(low[u],dfn[v]);//否則 如果v沒有已強連通,更新 }if(low[u]==dfn[u]){ ++scc;//scc為強連通數記錄器 while(1){int x=s.top();s.pop();sccno[x]=scc;//標記屬於的強連通序號 ,並出隊(抹掉) if(x==u)break;/*出隊完畢*/}}}int main(){int i,j; scanf("%d",&n); for(i=1;i<=n;++i)for(scanf("%d",&j);j;scanf("%d",&j))g[i].push_back(j);//奇妙IME for(i=1;i<=n;++i) if(!dfn[i]) t(i); for(i=1;i<=n;++i)for(j=0;j<g[i].size();++j){ int v=g[i][j]; if(sccno[i]!=sccno[v])++in[sccno[v]],++out[sccno[i]];//串連被縮點後的強連通圖 ,更新入度,出度 } for(i=1;i<=scc;++i)inc+=in[i]==0?1:0,outc+=out[i]==0?1:0;//如果入度為0,加入inc,如果出度為0,加入outc if(scc==1) puts("1\n0");//特殊情況,只有一個強連通圖,即本身就是個強連通圖 else printf("%d\n%d\n",inc,max(inc,outc));return 0;//否則,正常情況輸出 }
program is just above,the program is the best language
P2746 [USACO5.3]校園網Network of Schools