1. 程式人生 > >hdu-5786(補圖最短路)

hdu-5786(補圖最短路)

最短 can 我們 ace int 不用 scan csharp std

題意:給你n個點,m條無向邊,問你這n個點構成的完全圖,不用那m條邊,由一個s出現的單源最短路

解題思路:首先,暴力建圖不行,點太多,那麽我們就按照它的規則來,把m條邊建好,但是建的這個圖表示不走的方法,然後我們需要用一個東西來保存去除這些直接相連的邊的其它點,用set

代碼:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<queue>
#include<cstdio>
using namespace std;
const int maxn=200500;
const int inf=0x3f3f3f3f;
struct Edge
{
    int next;
    int to;
}edge[maxn];
int head[maxn];
int visit[maxn];
int dist[maxn];
int cnt;
int n,m;
int start;
set<int>s;
void add(int u,int v)
{
    edge[cnt].next=head[u];edge[cnt].to=v;head[u]=cnt++;
}
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
}
void bfs(int u)
{
    fill(dist+1,dist+1+n,inf);
    queue<int>q;
    q.push(u);
    set<int>s1,s2;//s2保存未拓展的點,既還沒有到達可能由其它點中轉的點;
    dist[u]=0;
    for(int i=1;i<=n;i++)
        if(i!=u)
        s1.insert(i);//先把所有點加入
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(!s1.count(v))//如果這個點被直接連邊,那麽這條邊不算
                continue;
            s1.erase(v);
            s2.insert(v);//把這個點扔到沒法拓展的點裏面
        }
        for(set<int>::iterator it=s1.begin();it!=s1.end();it++)
        {
            q.push(*it);
            dist[*it]=dist[now]+1;
        }
        s1.swap(s2);
        s2.clear();
    }
}
int main()
{
    int tt;
    int u,v;
    while(scanf("%d",&tt)!=EOF)
    {
        while(tt--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v);add(v,u);
            }
            scanf("%d",&start);
        bfs(start);//開始
        int cot=0;
        for(int i=1; i<=n; i++)
        {

            if(i==start)
                continue;cot++;
            if(dist[i]==inf)
                cout<<-1;
            else
                cout<<dist[i];
            if(cot<=n-2)
                cout<<" ";
        }
        cout<<endl;
        }
    }
}

  

hdu-5786(補圖最短路)