作這題是由於這是咱們做業......node
題目意思很簡單,求全部割點以及割開之後的點數ios
作法1:算法
nm的暴力直接上...ide
暴力割哪一個點spa
是能過的.....blog
作法2:input
二分+並查集string
咱們維護一個並查集,而後先把編號在[n/2,n]的邊加進去it
而後再dfs下去,每次加一些邊,直到dfs到某個點爲止io
那麼這樣咱們就能夠統計出在每一個點的時候一共合併了多少次並查集,複雜度O(alpha * m log n),
若是咱們把並查集當作O(1)的那麼就是O(m log n)
這個辦法寫起來挺麻煩的
作法3:
用tarjan來求雙連通份量的那個算法跑一邊
可是咱們再也不關心雙連通份量,而是考察每一個節點在dfs過去並回來的時候,low是否小於當前節點的dfn
若是是的,那麼刪除這個點之後,這個部分將會被割開
注意處理下根的狀況
代碼1:
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<math.h> #include<time.h> #include<vector> #include<bitset> #include<memory> #include<utility> #include<fstream> #include<stdio.h> #include<sstream> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; struct edge { int y; edge * next; }; edge * li[1005]; int top=0; edge * new_edge() { static edge a[1000005]; return &a[top++]; } void inserts(int x,int y) { edge * t=new_edge(); t->y=y; t->next=li[x]; li[x]=t; } void insert_edge(int x,int y) { inserts(x,y); inserts(y,x); } bool vis[1005]; void dfs(int x,int y) { if (x==y) { return; } vis[x]=true; edge * t; for (t=li[x];t!=0;t=t->next) { if (vis[t->y]) { continue; } if (t->y==y) { continue; } dfs(t->y,y); } } int a[1005]; int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int zu; for (zu=1;;zu++) { top=0; memset(li,0,sizeof(li)); int cnt=0; for (;;) { int x,y; scanf("%d",&x); if (x==0) break; scanf("%d",&y); x--; y--; a[cnt++]=x; a[cnt++]=y; insert_edge(x,y); } if (cnt==0) { break; } printf("Network #%d\n",zu); sort(a,a+cnt); int n=unique(a,a+cnt)-a; memset(vis,0,sizeof(vis)); int sum=0; int i; for (i=0;i<n;i++) { if (!vis[i]) { dfs(i,-1); sum++; } } bool nospf=true; for (i=0;i<n;i++) { //destroy i int j; memset(vis,0,sizeof(vis)); int sum2=0; for (j=0;j<n;j++) { if (j==i) { continue; } if (!vis[j]) { dfs(a[j],a[i]); sum2++; } } if (sum2>sum) { nospf=false; printf(" SPF node %d leaves %d subnets\n",i+1,sum2); } } if (nospf) { puts(" No SPF nodes"); } puts(""); } return 0; }
代碼2:
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<math.h> #include<time.h> #include<vector> #include<bitset> #include<memory> #include<utility> #include<fstream> #include<stdio.h> #include<sstream> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; struct edge { int y; edge * next; }; edge * li[1005]; int top=0; edge * new_edge() { static edge a[1000005]; return &a[top++]; } void inserts(int x,int y) { edge * t=new_edge(); t->y=y; t->next=li[x]; li[x]=t; } void insert_edge(int x,int y) { inserts(x,y); inserts(y,x); } int a[1005]; int findroot(vector<int> &fa,int x) { int root; for (root=x;fa[root]!=-1;root=fa[root]) ; int temp; for (;fa[x]!=-1;) { temp=fa[x]; fa[x]=root; x=temp; } return root; } int u(vector<int> &fa,vector<int> &size,int x,int y) { x=findroot(fa,x); y=findroot(fa,y); if (x==y) { return 0; } if (size[x]>size[y]) { swap(x,y); } fa[x]=y; size[y]+=size[x]; return 1; } bool inside(int l,int r,int x) { if ((l<=x)&&(x<r)) { return true; } return false; } int std_ans; vector<pair<int,int> > output_ans; void dfs(int l,int r,vector<int> fa,vector<int> size,int ans) { if (l==r-1) { if (ans>std_ans) { output_ans.push_back(make_pair(l+1,ans)); } return; } int mid=(l+r)/2; int i; vector<int> fa2=fa; vector<int> size2=size; int ans2=ans; for (i=mid;i<r;i++) { edge * t; for (t=li[i];t!=0;t=t->next) { if (inside(l,mid,t->y)) { continue; } ans2-=u(fa2,size2,i,t->y); } } dfs(l,mid,fa2,size2,ans2); for (i=l;i<mid;i++) { edge * t; for (t=li[i];t!=0;t=t->next) { if (inside(mid,r,t->y)) { continue; } ans-=u(fa,size,i,t->y); } } dfs(mid,r,fa,size,ans); } int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int zu; for (zu=1;;zu++) { top=0; memset(li,0,sizeof(li)); int cnt=0; for (;;) { int x,y; scanf("%d",&x); if (x==0) break; scanf("%d",&y); x--; y--; a[cnt++]=x; a[cnt++]=y; insert_edge(x,y); } if (cnt==0) { break; } printf("Network #%d\n",zu); sort(a,a+cnt); int n=unique(a,a+cnt)-a; vector<int> fa,size; fa.resize(n); size.resize(n); int i; for (i=0;i<n;i++) { fa[i]=-1; size[i]=1; } std_ans=n; for (i=0;i<n;i++) { edge * t; for (t=li[i];t!=0;t=t->next) { std_ans-=u(fa,size,i,t->y); } } for (i=0;i<n;i++) { fa[i]=-1; size[i]=1; } output_ans.clear(); dfs(0,n,fa,size,n-1); for (i=0;i<(int)output_ans.size();i++) { printf(" SPF node %d leaves %d subnets\n",output_ans[i].first,output_ans[i].second); } if (output_ans.size()==0) { puts(" No SPF nodes"); } puts(""); } return 0; }
代碼3:
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<math.h> #include<time.h> #include<vector> #include<bitset> #include<memory> #include<utility> #include<fstream> #include<stdio.h> #include<sstream> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; struct edge { int y; edge * next; }; edge * li[1005]; int top=0; edge * new_edge() { static edge a[1000005]; return &a[top++]; } void inserts(int x,int y) { edge * t=new_edge(); t->y=y; t->next=li[x]; li[x]=t; } int ans[1005]; void insert_edge(int x,int y) { inserts(x,y); inserts(y,x); } bool inque[1005]; int dfn[1005]; int low[1005]; int val=0; void scc(int x) { dfn[x]=val++; low[x]=dfn[x]; inque[x]=true; edge * t; for (t=li[x];t!=0;t=t->next) { if (dfn[t->y]==-1) { scc(t->y); if (low[t->y]>=dfn[x]) { ans[x]++; } low[x]=min(low[x],low[t->y]); } else if (inque[t->y]) { low[x]=min(low[x],dfn[t->y]); } } } int a[1005]; int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int zu; for (zu=1;;zu++) { top=0; memset(li,0,sizeof(li)); int cnt=0; for (;;) { int x,y; scanf("%d",&x); if (x==0) break; scanf("%d",&y); x--; y--; a[cnt++]=x; a[cnt++]=y; insert_edge(x,y); } if (cnt==0) { break; } printf("Network #%d\n",zu); sort(a,a+cnt); int n=unique(a,a+cnt)-a; memset(dfn,-1,sizeof(dfn)); memset(ans,0,sizeof(ans)); memset(inque,0,sizeof(inque)); val=0; int i; int cnts=0; for (i=0;i<n;i++) { if (dfn[i]==-1) { cnts++; scc(i); ans[i]--; } } bool nospf=true; for (i=0;i<n;i++) { if (ans[i]>0) { nospf=false; printf(" SPF node %d leaves %d subnets\n",i+1,ans[i]+cnts); } } if (nospf) { puts(" No SPF nodes"); } puts(""); } return 0; }