HDU 5876 Sparse Graph

题目: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代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<math.h>
  5 #include<set>
  6 #include<map>
  7 #include<list>
  8 #include<stack>
  9 #include<queue>
 10 #include<vector>
 11 #include<string>
 12 #include<iostream>
 13 #include<algorithm>
 14 using namespace std;
 15 #define lson rt<<1
 16 #define rson rt<<1|1
 17 #define N 200010
 18 #define M 100010
 19 #define Mod 1000000007
 20 #define LL long long
 21 #define INF 0x7fffffff
 22 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 23 #define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
 24 #define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
 25 #define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
 26 #define MT(x,i) memset(x,i,sizeof(x))
 27 #define gcd(x,y) __gcd(x,y)
 28 const double PI = acos(-1);
 29
 30 bool ad[N];
 31 int len[N];
 32 vector<int> v[N];
 33 vector<int> zan;
 34 set<int> st;
 35 int main()
 36 {
 37   int t,n,m,x,y;
 38   scanf("%d",&t);
 39   while(t--)
 40   {
 41     scanf("%d%d",&n,&m);
 42     while(m--)
 43     {
 44       scanf("%d%d",&x,&y);
 45       v[x].push_back(y);
 46       v[y].push_back(x);
 47     }
 48     int s,co=1;
 49     scanf("%d",&s);
 50     st.clear();
 51     MT(ad,0);
 52     ad[s]=true;
 53     For(i,0,v[s].size()){
 54       ad[v[s][i]]=true;
 55     }
 56
 57     MT(len,-1);
 58     FOR(i,1,n){
 59       if(i==s) continue;
 60       if(ad[i]==false){
 61         len[i]=1;
 62         co++;
 63         ad[i]=true;
 64       }
 65       else{
 66         st.insert(i);
 67         ad[i]=false;
 68       }
 69     }
 70     int ll=2;
 71     while(1)
 72     {
 73       zan.clear();
 74       bool ff=false;
 75       for(set<int>::iterator it=st.begin();it!=st.end();it++)
 76       {
 77         int x=*it;
 78         bool flag=false;
 79         if(v[x].size()<co)
 80         {
 81           flag=true;
 82         }
 83         else
 84         {
 85           int k=v[x].size();
 86           For(i,0,v[x].size())
 87           {
 88             int son=v[x][i];
 89             if(ad[son]==false) k--;
 90             if(k<co) break;
 91           }
 92           if(k<co)
 93           {
 94             flag=true;
 95           }
 96         }
 97         if(flag==true)
 98         {
 99           ff=true;
100           zan.push_back(x);
101         }
102       }
103       if(ff==false) break;
104       For(i,0,zan.size())
105       {
106         ad[zan[i]]=true;
107         len[zan[i]]=ll;
108         co++;
109       }
110       ll++;
111       for(set<int>::iterator it=st.begin();it!=st.end();)
112       {
113         int x=*it;
114         if(ad[x]==true) st.erase(it++);
115         else it++;
116       }
117     }
118     bool ff=false;
119     FOR(i,1,n){
120       if(i!=s){
121         if(ff!=false) printf(" ");
122         else ff=true;
123         printf("%d",len[i]);
124       }
125     }
126     printf("\n");
127     FOR(i,1,n){
128       v[i].clear();
129     }
130   }
131   return 0;
132 }
时间: 2024-08-06 07:59:09

HDU 5876 Sparse Graph的相关文章

hdu 5876 Sparse Graph 无权图bfs求最短路

Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if

HDU 5876 Sparse Graph BFS 最短路

Sparse Graph Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if and only if they are notadjacent in G. Now you are given an undirected graph G of N n

HDU 5876 Sparse Graph(补图中求最短路)

http://acm.hdu.edu.cn/showproblem.php?pid=5876 题意: 在补图中求s到其余各个点的最短路. 思路:因为这道题目每条边的距离都是1,所以可以直接用bfs来做. 处理的方法是开两个集合,一个存储当前顶点可以到达的点,另一个存储当前顶点不能到达的点.如果可以到达,那肯定由该顶点到达是最短的,如果不能,那就留着下一次再判. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstr

HDU 5876 Sparse Graph(补图上BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5876 题意: 有一个 n 个点无向图,再给你 m 对顶点, 代表着这 m 对顶点之间没有边, 除此之外每两个点之间都有一条边, 且权值为 1.然后还有一个源点 S, 让你计算源点到其他各点之间的最短距离,如果不存在则输出 -1.也就是说让你在所给的图的补图上求源点到其他各点的最短路径. 思路: 补图上求最短路径算是比较经典的题.在这里所求的最短路其实并不需要用到 dijkstra 之类的算法,由于每

HDU 5867 Sparse Graph (2016年大连网络赛 I bfs+补图)

题意:给你n个点m条边形成一个无向图,问你求出给定点在此图的补图上到每个点距离的最小值,每条边距离为1 补图:完全图减去原图 完全图:每两个点都相连的图 其实就是一个有技巧的bfs,我们可以看到虽然点很多但边很少,就使用vector存下每个点在原图中可以到达其他的哪些点,再使用bfs寻找此时起点可以到的其他点(每个距离都是1,所以越早到距离越短),接着更新起点继续查找:我们需要使用数组记录此时起点不能到的一些点(就是vector中原图起点可以到的点),但每次通过起点判断其他所有的点会超时,因此我

HDU 5876:Sparse Graph(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=5876 Sparse Graph Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if and only if they are not adjacent in G

2016大连网络赛 Sparse Graph

Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if

hdu5876 Sparse Graph(补图最短路)

题目链接:hdu5876 Sparse Graph 一开始用vector一直TLE,然后就没有然后了.. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<vector> 6 #include<set> 7 using namespace std; 8 9 const int N = 200001; 10

HDU 5876 补图 单源 最短路

---恢复内容开始--- Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2590    Accepted Submission(s): 902 Problem Description In graph theory, the complement of a graph G is a graph H on t