[POJ3417]Network

來源:互聯網
上載者:User

標籤:net   turn   std   amp   int   nbsp   poj   main   roo   

思路:
考慮加入新邊對原圖的影響:
  每加入一條邊,相當於在原圖中構成一個環,因此要使原圖在這個環上斷開,必須刪去這條新邊和環上任意一條樹邊。
統計每一條樹邊出現在多少個環中,計作$c$:
  1.$c=0$,則該邊不屬於任何一個環,因此刪去這條邊的同時刪去任意一條新邊即可,對答案的貢獻是$m$;
  2.$c=1$,則該邊僅屬於一個環,因此刪去這條邊並刪去該環上的新邊即可,對答案的貢獻是$1$;
  3.$c\geq 2$,則該邊同時包含於多個環中,無論刪去哪一個新邊,總有別的環使原圖連通,對答案的貢獻是$0$。
因此我們可以統計$c$來得到答案。
我們可以利用樹上差分的思想,對於每條新邊$(u,v)$,$f_u=f_u+1$,$f_v=f_v+1$,$f_{LCA(u,v)}=f_{LCA(u,v)}+1$。
最後用樹形DP求出每條邊被環包含的次數。
Tarjan求LCA。
但是在OJ上測會TLE,必須要把vector改成前向星才可以。

 

 1 #include<cstdio> 2 #include<cctype> 3 inline int getint() { 4     char ch; 5     while(!isdigit(ch=getchar())); 6     int x=ch^‘0‘; 7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘); 8     return x; 9 }10 const int root=1,nil=0;11 const int V=100001;12 struct Edge {13     int to,next;14 };15 int sz=0;16 Edge edge[V<<2];17 int e[V]={0},q[V]={0};18 inline void add_edge(const int u,const int v) {19     edge[++sz]=(Edge){v,e[u]};20     e[u]=sz;21 }22 inline void add_query(const int u,const int v) {23     edge[++sz]=(Edge){v,q[u]};24     q[u]=sz;25 }26 class DisjointSet {27     private:28         int anc[V];29     public:30         DisjointSet() {31             for(int i=0;i<V;i++) anc[i]=i;32         }33         int Find(const int x) {34             return x==anc[x]?x:anc[x]=Find(anc[x]);35         }36         void Union(const int x,const int y) {37             anc[Find(x)]=Find(y);38         }39 };40 DisjointSet s;41 bool vis[V]={0};42 int f[V]={0};43 void Tarjan(const int x,const int par) {44     for(int i=e[x];i;i=edge[i].next) {45         int &y=edge[i].to;46         if(y!=par) Tarjan(y,x);47     }48     for(int i=q[x];i;i=edge[i].next) {49         int &y=edge[i].to;50         if(!vis[y]) continue;51         int lca=s.Find(y);52         f[x]++,f[y]++,f[lca]-=2;53     }54     s.Union(x,par);55     vis[x]=true;56 }57 int cnt[2]={-1};58 void DP(const int x,const int par) {59     for(int i=e[x];i;i=edge[i].next) {60         int &y=edge[i].to;61         if(y==par) continue;62         DP(y,x);63         f[x]+=f[y];64     }65     if(f[x]<2) cnt[f[x]]++;66 }67 int main() {68     int n=getint(),m=getint();69     for(int i=1;i<n;i++) {70         int u=getint(),v=getint();71         add_edge(u,v);72         add_edge(v,u);73     }74     for(int i=1;i<=m;i++) {75         int u=getint(),v=getint();76         add_query(u,v);77         add_query(v,u);78     }79     Tarjan(root,nil);80     DP(root,nil);81     printf("%d\n",cnt[0]*m+cnt[1]);82     return 0;83 }

 

[POJ3417]Network

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.