標籤:
據說這是一道Word Final的題,Orz。。。
原題連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3136
題意:
給你一個聯通圖,讓你選擇一些點,使得這個圖的任意一個點消失後,其餘的點都能到達某個你選擇的點。問你最少選擇哪些點,並且輸出在最優的情況下,有多少方案。
題解:
一眼看過去,做法很簡單,就刪掉所有的割點後,考察聯通塊的個數就好。但這道題滿滿的坑。。要不怎麼是總決賽的題。。
首先如果這個圖只有一個聯通塊,那麼答案就應該是任選兩個點,這是因為,如果其中一個點掛了,還能走另外一個點。
如果一個聯通塊有大於一個割點,那麼這個聯通塊就不需要,這是因為兩個割點不可能同時掛了。
代碼:
#include<iostream>#include<cstring>#include<algorithm>#include<vector>#include<set>#define MAX_V 50004using namespace std;int V=0;vector<int> G[MAX_V];int N;int dfn[MAX_V],low[MAX_V],ind=0;bool vis[MAX_V];bool isCut[MAX_V];int tot=0;long long ways=1;long long tmp=0;long long cnt=0;bool used[MAX_V];set<int> se;void init(){ se.clear(); V=ind=cnt=tmp=0; ways=1; memset(used,0,sizeof(used)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(isCut,0,sizeof(isCut)); for(int i=0;i<=N+2;i++)G[i].clear();}void Tarjan(int u,int p) { dfn[u] = low[u] = ++ind; vis[u]=1; int child = 0; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == p)continue; if (!vis[v]) { child++; Tarjan(v, u); low[u] = min(low[v], low[u]); if (p == 0 && child > 1)isCut[u] = 1; if (p&&low[v] >= dfn[u]) isCut[u] = 1; tot+=isCut[u]; } else low[u] = min(dfn[v], low[u]); }}void dfs(int u) { if (used[u] || isCut[u])return; tmp++; used[u] = 1; for (int i = 0; i < G[u].size(); i++){ int v=G[u][i]; if(isCut[v]){ se.insert(v); continue; } dfs(v); }}int main() { int cas = 0; cin.sync_with_stdio(false); while (cin >> N) { tot=0; if (N == 0)break; init(); for (int i = 0; i < N; i++) { int u, v; cin >> u >> v; V = max(V, max(u, v)); G[u].push_back(v); G[v].push_back(u); } Tarjan(1, 0); cout << "Case " << ++cas << ": "; if (tot == 0) { cout << 2 << " " << (long long)V * (V - 1) / 2 << endl; continue; } for (int u = 1; u <= V; u++) { if (isCut[u])continue; tmp = 0; if (!used[u]) { se.clear(); dfs(u); if (se.size() == 1 && tmp) { ways *= tmp; cnt++; } } } cout << cnt << " " << ways << endl; } return 0;}
UVALive 5135 Mining Your Own Business 雙連通分量