標籤:
http://acm.timus.ru/problem.aspx?space=1&num=15571557. Network AttackTime limit: 2.0 second
Memory limit: 64 MBIn some computer company, Mouse Inc., there is very complicated network structure. There are a lot of branches in different countries, so the only way to communicate with each other is the Internet. And it‘s worth to say that interaction is the key to the popularity and success of the Mouse Inc.The CEO of this company is interested now to figure out whether there is a way to attack and devastate whole structure. Only two hackers are capable to perpetrate such an outrage — Vasya and Petya, who can destroy any two channels. If after that there are at least two servers without connection between them, then they succeed.In other words, the company is a set of servers, some of them connected with bidirectional channels. It‘s guaranteed that all the servers are connected directly or indirectly. The hackers‘ goal is to divide network into at least two parts without any connection between them. Each hacker can destroy exactly one channel. And they can‘t destroy the same channel together. You are asked to count the number of ways for hackers to win.InputThere are two integer numbers (
N,
M) in the first line of input: the number of servers and channels respectively (1 ≤
N ≤ 2000; 0 ≤
M ≤ 100000). In the each of the next
M lines there are exactly two numbers — the indices of servers connected by channel. Channels can connect a server to itself. There can be multiple channels between one pair of servers. The servers are numbered from 1 to
N.OutputThere must be exactly one integer — the answer to the question described in the problem.Sample
input |
output |
3 31 22 33 1 |
3 |
Problem Source: Novosibirsk SU Contest. Petrozavodsk training camp, September 2007 思路:首先dfs建樹,這個時候圖就只分為樹邊和回邊,自邊(回邊+自邊=非樹邊),(沒有橫邊),分隔方案有三種1:拆除的一條邊是橋,另外一條隨便,這個用tarjian演算法解決,設橋的數量為nb,總邊數m,則第一類方案數為(m-nb)*nb+nb*(nb-1)/22:拆除兩條邊後分離出了一棵子樹,這時候一定一條邊是樹邊(肯定不是橋邊),另外一條是回邊,只需要統計一下,設b[s]儲存以s為頂點的子樹到s的祖先的邊數,b[s]==2就有一種方案3:拆除兩條邊後分離出了子樹的一部分,:分出中間那部分,剩下兩部分可以相連,這就要求中間部分到上面部分(祖先)和下面部分(分出來的子樹)間都沒有邊相連,明顯,毀壞的必須是兩條樹邊,而且不是橋邊(需要b[s]>1,b[son]>1)記錄深度數組dfn[],分出來的子樹的回邊所能到達的最低深度為high[]數組,那麼當我們確定要毀壞的是s和父親的樹邊時,需要搜尋s有沒有滿足條件的配對點son來破壞son和其父親間的樹邊使得中間部分脫離,此時必須有high[son]<dfn[s],使得上面部分到中間部分沒有邊,下面部分到中間部分也沒有邊.但是注意,中間部分可能有內部的回邊,所以要控制b[s]==b[son],使得b[son]和b[s]之間沒有未被接收的回邊 感想:這題思路似乎很簡單,但是一開始考慮的是,設由祖先向節點s的子樹連所連的最淺子節點深度為high[s](通過非樹邊),則第三類點一定在這個點上面,但是這樣做的話,無法規避這種情況於是,再設一個條件,第三類合格點要滿足其深度大於"深度大於s節點的祖先"(s的兒子,合格點的祖先)所能連到的最深深度,不過還是不能過Test#16最後還是直接使用了上交紅書的方法
#include <cstdio>#include <cstring>#include <algorithm>#include <stack>using namespace std;typedef long long ll;const int maxn=2002,maxm=200002;//ATTENTION,undirectint n,m;ll ans,nb;int b[maxn];int c[maxn];//edge to its father,select and acceedint first[maxn];int next[maxm];bool tree[maxm];int to[maxm];int brg[maxm];//bridgeint dfn[maxn],high[maxn],depth;bool up[maxn][maxn];void dfs(int s,int aim){ for(int p=first[s];p!=-1;p=next[p]){ if(tree[p]){ dfs(to[p],aim); } } if(c[s]==1&&b[s]==b[aim]&&high[s]<dfn[aim]){ // printf("b:%d %d\n",aim,s); ans++; } // return ans;}void addedge(int f,int t,int ind){ next[ind]=first[f]; first[f]=ind; to[ind]=t; swap(f,t);ind++; next[ind]=first[f]; first[f]=ind; to[ind]=t;}void tarjan(int s,int pf){ dfn[s]=++depth; for(int p=first[s];p!=-1;p=next[p]){ if(s==to[p]){continue;} if(pf>=0&&to[p]==to[pf^1])c[s]++; if((p|1)==(pf|1)){b[s]++;continue;} if(dfn[to[p]]==0){ tree[p]=true; tarjan(to[p],p); if(b[to[p]]==1){ brg[nb++]=p; } b[s]+=b[to[p]]-1; for(int i=1;i<=dfn[s];i++){ if(up[to[p]][i])up[s][i]=true; } } else { if(dfn[to[p]]>dfn[s]){ b[s]--; } else { up[s][dfn[to[p]]]=true; b[s]++; } } } high[s]=dfn[to[pf^1]]; for(int i=dfn[to[pf^1]];i>=0;i--){ if(up[s][i]){high[s]=i;break;} } if(b[s]==2)ans++; if(c[s]==1&&b[s]>1){ for(int p=first[s];p!=-1;p=next[p]){ if(tree[p]){ dfs(to[p],s); } } }}int main(){ scanf("%d%d",&n,&m); memset(first,-1,sizeof(first)); for(int i=0;i<m;i++){ int f,t; scanf("%d%d",&f,&t); addedge(f,t,2*i); } tarjan(1,-1); ans+=(m-nb)*nb+nb*(nb-1)/2; printf("%I64d\n",ans); return 0;}
URAL 1557 Network Attack 圖論,連通性,tarjain,dfs建樹,分類討論 難度:2