P3106 [USACO14OPEN] GPS duel (shortest)

 

 Simplification: Enough of the Jane ..... but! Translation absolutely pot.

The shortest path is the shortest path from a single source to each point n, which is the shortest path tree.

So, the idea is very clear. FIG build two, and then run on both sides of the SPFA, record the shortest path.

Then, for the edge between two points, if it does not pass through the shortest path, then the right side of FIG eventually +1;

Then on the final map (right side 0,1,2) SPFA to run again.

At first I think complicated, wondering how the recording path, how reconstruction drawing .balabala.

Then find how to make two points on the shortest path is not it?

SPFA relaxation operation, based on the triangle inequality. So, if the shortest distance between two points, if not equal to the right side (that is, the shortest path between the sides but Talia) then it will alarm is a side.

$$ SPFA seems most important is the triangle inequality $$

So, as long as the violence SPFA can run three times.

Exhausted every means, faith SPFA, various constants optimization, hang read, I still could not go to the first surface of the optimal solution .... In the second page of the first few wandering .....

Code :( such a long view of the topic are rare, but it seems so long on the park)

#include<iostream>
#include<cstdio>
#include<queue>
#define rg register
using namespace std;
const int maxn=1e6+10;
int n,m;
inline int read()
{
    int x=0,f=1;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
struct edge
{
    int to,next,dis;
}e1[maxn],e2[maxn],e[maxn];
int head[maxn],head1[maxn],head2[maxn];
int cnt1,cnt2,cnt;
inline void addedge1(int from,int to,int dis)
{
    e1[++cnt1].next=head1[from];
    e1 [cnt1] .TO = to?
    e1 [TCNT1] .dis = December;
    head1[from]=cnt1;
}
inline void addedge2(int from,int to,int dis)
{
    e2[++cnt2].next=head2[from];
    e2[cnt2].to=to;
    e2 [cnt2] .dis = December;
    head2[from]=cnt2;
}
inline void addedge(int from,int to,int dis)
{
    e[++cnt].next=head[from];
    e [cnt] .TO = to?
    e [cnt] .dis = say;
    head[from]=cnt;
}

int dis1[maxn],vis1[maxn],pre1[maxn];
struct cmp1
{
    bool operator () (int a,int b)
    {
        return dis1[a]>dis1[b];
    }
};
inline void spfa1()
{
    priority_queue < int , vector < int > , cmp1 > q;
    for(rg int i=1;i<=n;i++)
    {
        DIS1 [i] = 2147483647 ;
        vis1 [i] = 0 ;
    }
    q.push(n);
    DIS1 [n] = 0 ;
    vis1[n]=1;
    while(!q.empty())
    {
        int u=q.top();
        q.pop();
        vis1[u]=0;
        for(rg int i=head1[u];i;i=e1[i].next)
        {
            int v=e1[i].to;
            if(dis1[v]>dis1[u]+e1[i].dis)
            {
                dis1 [v] = dis1 [u] + e1 [i] .dis;
                if (vis1 [v] == 0 )
                {
                    vis1 [v] = 1 ;
                    q.push(v);
                }
            }
        }
    }
}
int dis2[maxn],vis2[maxn],pre2[maxn];
struct cmp2
{
    bool operator () (int a,int b)
    {
        return dis2[a]>dis2[b];
    }
};
inline void spfa2()
{
    priority_queue < int , vector < int > , cmp2 > q;
    for(rg int i=1;i<=n;i++)
    {
        dis2[i]=2147483647;
        vis2 [i] = 0 ;
    }
    q.push(n);
    dis2[n]=0;
    vis2[n]=1;
    while(!q.empty())
    {
        int u=q.top();
        q.pop();
        vis2[u]=0;
        for(rg int i=head2[u];i;i=e2[i].next)
        {
            int v=e2[i].to;
            if(dis2[v]>dis2[u]+e2[i].dis)
            {
                dis2[v]=dis2[u]+e2[i].dis;
                if(vis2[v]==0)
                {
                    vis2 [v] = 1 ;
                    q.push(v);
                }
            }
        }
    }
}
int dis[maxn],vis[maxn];
struct cmp
{
    bool operator () (int a,int b)
    {
        return dis[a]>dis[b];
    }
};
inline void rebuild()
{
    for(rg int i=1;i<=n;i++)
    {
        for(int j=head1[i];j;j=e1[j].next)
        {
            int v1=e1[j].to;
            int v2=e2[j].to;
            //cout<<i<<' '<<v1<<endl;
            int d=0;
            if(dis1[v1]-dis1[i]!=e1[j].dis)
            d++;
            if(dis2[v2]-dis2[i]!=e2[j].dis)
            d++;
            addedge(v1,i,d);
        }
    }
}
inline void spfa()
{
    priority_queue < int , vector < int > , cmp > q;
    for(rg int i=1;i<=n;i++)
    {
        December [i] = 2147483647 ;
        view [i] = 0 ;
    }
    q.push(1);
    dis[1]=0;
    vis[1]=1;
    while(!q.empty())
    {
        int u=q.top();
        q.pop();
        vis[u]=0;
        for(rg int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].dis)
            {
                dis[v]=dis[u]+e[i].dis;
                if(vis[v]==0)
                {
                    to [v] = 1 ;
                    q.push(v);
                }
            }
        }
    }
}
int main ()
{
    n=read();
    m=read();
    for(rg int i=1;i<=m;i++)
    {
        int a=read(),b=read(),c=read(),d=read();
        //scanf("%d%d%d%d",&a,&b,&c,&d);
        addedge1(b,a,c);
        addedge2(b,a,d);
        //addedge(a,b,0);
    }
    spfa1 ();
    spfa2();
    rebuild();
    spfa();
    printf("%d",dis[n]);
    return 0;
}

(Finish)

 

Guess you like

Origin www.cnblogs.com/ajmddzp/p/11780356.html