Roads and Airways Blue Bridge Zhenti

http://lx.lanqiao.cn/problem.page?gpid=T22

Because there is a negative weight side, only spfa can be used, but the data is relatively strong and can only achieve 95 points. . There may be other ways

Mainly remember the two optimizations of spfa

The first is SLF, which is to use a double-ended queue instead. When a point v enters the queue, it determines the size relationship between it and the front of the queue. If the queue is empty or dis[v]>=dis[front], then throw v to the end of the queue Otherwise, throw it to the head of the team

The second is that when LLL pops the head of the team at the beginning of the loop, if the average of the current head of the team is greater than the average of all points in the queue, it will be thrown to the tail of the queue until the point of the current head of the team is less than or equal to the average. its pop queue

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=0x3f3f3f3f;
const int maxn=3e4+10;
const int maxm=5e4+10;

struct node
{
    int v,w,next;
};

deque <int> que;
node edge[3*maxm];
int first[maxn],dis[maxn],book[maxn];
int n,m1,m2,s,num;

template <class T>
inline void _cin(T &ret)		//读正负整数 (int, long long)
{
    char ch;
    int flag = 0;
    while((ch = getchar()) < '0' || ch > '9')
    {
        if(ch == '-') flag = 1;
    }
    for(ret = 0; ch >= '0' && ch <= '9'; ch = getchar())
    	ret = ret * 10 + ch - '0';
    if(flag) ret *= -1;
}

void addedge(int u,int v,int w)
{
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=first[u];
    first[u]=num++;
}

void spfa()
{
    ll sum;
    int i,u,v,w,cnt;
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0,book[s]=1;
    que.push_back(s);
    cnt=1,sum=0;
    while(!que.empty()){
        u=que.front();
        while(ll(cnt)*ll(dis[u])>sum){
            //printf("*%d*\n",u);
            que.pop_front();
            que.push_back(u);
            u=que.front();
        }
        que.pop_front();
        book[u]=0;
        cnt--,sum-=dis[u];
        for(i=first[u];i!=-1;i=edge[i].next){
            v=edge[i].v,w=edge[i].w;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                if(!book[v]){
                    book[v]=1;
                    if(que.empty()||dis[v]>dis[que.front()]) que.push_back(v);
                    else que.push_front(v);
                    cnt++,sum+=dis[v];
                }
            }
        }
    }

}

int main()
{
    int i,u,v,w;
    //scanf("%d%d%d%d",&n,&m1,&m2,&s);
    _cin(n),_cin(m1),_cin(m2),_cin(s);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=m1;i++){
        //scanf("%d%d%d",&u,&v,&w);
        _cin(u),_cin(v),_cin(w);
        addedge(u,v,w);
        addedge(v,u,w);
    }
    for(i=1;i<=m2;i++){
        //scanf("%d%d%d",&u,&v,&w);
        _cin(u),_cin(v),_cin(w);
        addedge(u,v,w);
    }
    spfa();
    for(i=1;i<=n;i++){
        if(dis[i]==N) printf("NO PATH\n");
        else printf("%d\n",dis[i]);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325397443&siteId=291194637