HDU 5876 Sparse Graph
2016-09-10 22:54
246 查看
题目:Sparse Graph
链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5876
题意:给出一个图(V<=20万,E<=2万),要求先化为补图(每两个点,原本有边删去边,原本没边添加边),然后问指定点S到其他每个点的最短距离。
思路:
普通的广搜应该解决不了。。。O(n*m)太大,不会很难,比赛时没做出来有点可惜,当知道过了也进不了时,就安慰了许多。
变化一下思路,从起点出发,因为原本边<=2万,那么大部分的点都已经可以到达了,也就是len=1(len最短距离),现在用集合st 来存放还没到达的点,用ad[i]=true来表示i 已经到达,用co表示已经到达的点的数量。每一次循环遍历st,对于某一个还没到达的点x ,假定和x 相邻的点有m 个,如果m<co,那说明x 肯定能到达。因为原本y 和x 没有边,补图里肯定就有,也就是说最坏情况是m个点对应的都是已经遍历过的,那么co-m这些点肯定能到达x。如果m>=co,并不能说明x 一定到不了,现在就要遍历m个点,如果某个点是没有遍历过的,m可以-1,如果最终m<co,说明x 还是可以遍历到的。每一次循环,就是找出若干个x ,x能到达,如果没有这样的x 就可以退出了,如果有,集合删去这些x,记录len,记录ad,记录co ,进入下次循环。
时间复杂度计算:集合最初最多2万个点,每次删掉就不恢复了,这里的时间为E,m>=co要找点时也就是遍历所有的边,每个边最多遍历1次,时间E。也就是说循环里看似套了很多层,其实很快,外面大概就是V,时间复杂度V+E。
AC代码:
链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5876
题意:给出一个图(V<=20万,E<=2万),要求先化为补图(每两个点,原本有边删去边,原本没边添加边),然后问指定点S到其他每个点的最短距离。
思路:
普通的广搜应该解决不了。。。O(n*m)太大,不会很难,比赛时没做出来有点可惜,当知道过了也进不了时,就安慰了许多。
变化一下思路,从起点出发,因为原本边<=2万,那么大部分的点都已经可以到达了,也就是len=1(len最短距离),现在用集合st 来存放还没到达的点,用ad[i]=true来表示i 已经到达,用co表示已经到达的点的数量。每一次循环遍历st,对于某一个还没到达的点x ,假定和x 相邻的点有m 个,如果m<co,那说明x 肯定能到达。因为原本y 和x 没有边,补图里肯定就有,也就是说最坏情况是m个点对应的都是已经遍历过的,那么co-m这些点肯定能到达x。如果m>=co,并不能说明x 一定到不了,现在就要遍历m个点,如果某个点是没有遍历过的,m可以-1,如果最终m<co,说明x 还是可以遍历到的。每一次循环,就是找出若干个x ,x能到达,如果没有这样的x 就可以退出了,如果有,集合删去这些x,记录len,记录ad,记录co ,进入下次循环。
时间复杂度计算:集合最初最多2万个点,每次删掉就不恢复了,这里的时间为E,m>=co要找点时也就是遍历所有的边,每个边最多遍历1次,时间E。也就是说循环里看似套了很多层,其实很快,外面大概就是V,时间复杂度V+E。
AC代码:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<set> #include<map> #include<list> #include<stack> #include<queue> #include<vector> #include<string> #include<iostream> #include<algorithm> using namespace std; #define lson rt<<1 #define rson rt<<1|1 #define N 200010 #define M 100010 #define Mod 1000000007 #define LL long long #define INF 0x7fffffff #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++) #define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++) #define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--) #define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--) #define MT(x,i) memset(x,i,sizeof(x)) #define gcd(x,y) __gcd(x,y) const double PI = acos(-1); bool ad ; int len ; vector<int> v ; vector<int> zan; set<int> st; int main() { int t,n,m,x,y; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } int s,co=1; scanf("%d",&s); st.clear(); MT(ad,0); ad[s]=true; For(i,0,v[s].size()){ ad[v[s][i]]=true; } MT(len,-1); FOR(i,1,n){ if(i==s) continue; if(ad[i]==false){ len[i]=1; co++; ad[i]=true; } else{ st.insert(i); ad[i]=false; } } int ll=2; while(1) { zan.clear(); bool ff=false; for(set<int>::iterator it=st.begin();it!=st.end();it++) { int x=*it; bool flag=false; if(v[x].size()<co) { flag=true; } else { int k=v[x].size(); For(i,0,v[x].size()) { int son=v[x][i]; if(ad[son]==false) k--; if(k<co) break; } if(k<co) { flag=true; } } if(flag==true) { ff=true; zan.push_back(x); } } if(ff==false) break; For(i,0,zan.size()) { ad[zan[i]]=true; len[zan[i]]=ll; co++; } ll++; for(set<int>::iterator it=st.begin();it!=st.end();) { int x=*it; if(ad[x]==true) st.erase(it++); else it++; } } bool ff=false; FOR(i,1,n){ if(i!=s){ if(ff!=false) printf(" "); else ff=true; printf("%d",len[i]); } } printf("\n"); FOR(i,1,n){ v[i].clear(); } } return 0; }
相关文章推荐
- HDU 5876 Sparse Graph (补图BFS+(链表||set))
- HDU - 5876 Sparse Graph (补图的最短路)
- HDU 5876 Sparse Graph
- HDU-5876 Sparse Graph
- HDU 5876 Sparse Graph
- HDU 5876 Sparse Graph
- HDU 5876 Sparse Graph
- hdu-5876-Sparse Graph
- HDU 5876 Sparse Graph
- Sparse Graph(HDU 5876)
- HDU 5876 2016 ACM/ICPC Asia Regional Dalian Online BFS+set
- HDU 5876 Sparse Graph(补图+BFS最短路)
- HDU 5876 Sparse Graph(bfs+set)
- HDU 5876 Sparse Graph BFS 最短路
- HDU - 5876(100/600)
- hdu 5876 Sparse Graph 完全图补图最短路
- hdu 5876 Sparse Graph【最短路+思维】好题
- HDU 5876 Sparse Graph(补图上BFS)
- hdu 5876 Sparse Graph(补图最短路) 2016 ACM/ICPC Asia Regional Dalian Online 1009
- 补图BFS(hdu 5876)