HDU5876 补图求最短路 2016ACM ICPC青岛网络赛

来源:互联网 发布:js filter 实现 编辑:程序博客网 时间:2024/05/16 12:59

题目

题意:给定一个无向图以及一个点s,求在其补图,点 s 到其他所有n-1个点的最短距离,并输出

思路:
以原图求补图,,bfs遍历,把与点u相连的点排除,不相邻的点在补图里都与点u可以有一条权为1的边,访问完之后即把这些点从set里删除。
同时在bfs的过程中,记录dis[i],每向外一层,为dis[i+1]=dis[i]+1;

#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<set>#include<queue>#include<cstring>using namespace std;const int N = 200010;typedef pair<int,int> aaa;int aa[N], in[N], T, n, m, s, flag;set<int>st[N], qry, pan;set<aaa>e;int dp[100][100];void find(){    queue<int>q;    set<int>::iterator it = pan.begin();    while (it != pan.end()) {q.push(*it);++it;}    while(!q.empty()){        int u = q.front(); q.pop();        for(set<int>::iterator it = qry.begin(); it != qry.end(); ){            if(e.count(aaa(min(u, *it), max(u, *it))) == 0){                q.push(*it);                aa[*it] = aa[u]+1;                set<int>::iterator tmp = it; tmp++;                qry.erase(it);                it = tmp;            }            else ++it;        }    }}int main() {    scanf("%d", &T);    while(T--){        scanf("%d%d", &n, &m);        memset(in, 0, sizeof(in));        for(int i = 1; i <= n; ++i) st[i].clear();        e.clear(); pan.clear(); qry.clear();        for(int a, b, i = 0; i < m; ++i){            scanf("%d%d", &a, &b);            if(a > b) swap(a, b);            in[a]++, in[b]++;            st[a].insert(b);            st[b].insert(a);            e.insert(aaa(a, b));        }        scanf("%d", &s);        for(int i = 1; i <= n; ++i){            if(i == s) continue;            if(st[s].count(i)) qry.insert(i);            else aa[i] = 1, pan.insert(i);        }        flag = 0;        for(int i = 1; i <= n; ++i){            if(in[i] == 0){                flag = 1;                break;            }        }        if(flag){            set<int>::iterator it = qry.begin();            while (it != qry.end()) {                aa[*it] = 2;                 ++it;            }        } else {            find();        }        flag = 0;        for(int i = 1; i <= n; ++i){            if(i == s) continue;            if(flag)                 printf(" ");            else                 flag = 1;            printf("%d", aa[i]);        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击