[SPFA]JZOJ 5869 绿洲

Description

 

Input

Output

 

Sample Input

5 7 2
2 3
1 2
1 3
1 4
2 4
3 4
3 5
4 5

Sample Output

1 2 2 1 2
 

Data Constraint

 

Hint

分析

显然我们对于每个绿洲求spfa即可

(为什么我dij堆优化炸了????)

 

#include <iostream>
#include <cstdio>
#include <deque>
#include <memory.h>
using namespace std;
const int N=1e5+10;
struct Edge {
    int v,nx;
}g[2*N];
int cnt,list[N],d[N],ans[N];
bool b[N],gr[N];
int n,m,k;

void Add(int u,int v) {
    g[++cnt].v=v;g[cnt].nx=list[u];list[u]=cnt;
}

void Spfa(int v0) {
    int cnt=1,sum=0;
    deque<int> q;
    while (!q.empty()) q.pop_front();
    memset(d,0x3f,sizeof d);memset(b,0,sizeof b);
    q.push_back(v0);
    d[v0]=0;b[v0]=1;
    while (!q.empty()) {
        int u=q.front();q.pop_front();
        if (d[u]*cnt>sum) {
            q.push_back(u);
            continue;
        }
        cnt--;sum-=d[u];
        for (int i=list[u];i;i=g[i].nx)
            if (d[g[i].v]>d[u]+1) {
                d[g[i].v]=d[u]+1;
                if (!b[g[i].v]) {
                    if (!q.empty()&&d[g[i].v]<d[q.front()])
                        q.push_front(g[i].v);
                    else q.push_back(g[i].v);
                    cnt++;sum+=d[g[i].v];
                }
                b[g[i].v]=1;
            }
        b[u]=1;
    }
}

int main() {
    freopen("oasis.in","r",stdin);
    freopen("oasis.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for (int i=1;i<=k;i++) {
        int id;
        scanf("%d",&id);
        gr[id]=1;
    }
    for (int i=1;i<=m;i++) {
        int u,v;
        scanf("%d%d",&u,&v);
        Add(u,v);Add(v,u);
    }
    for (int i=1;i<=n;i++)
        if (gr[i]) {
            Spfa(i);
            for (int i=1;i<=n;i++)
                ans[i]=max(ans[i],d[i]);
        }
    for (int i=1;i<=n;i++)
        printf("%d ",ans[i]);
    fclose(stdin);fclose(stdout);
}
View Code

 

posted @ 2018-09-15 13:59  Vagari  阅读(107)  评论(0编辑  收藏  举报