Good luck, chicken night!

Just playing for a \ (surviv \) , really cool ate three. . .

I do not hide the skin, and how could I fight \ (surviv \) such things?

About this question, I would like to call it strength of character Aotian love running · change every day!

First clear meaning of the questions, for any of the shortest path to go through \ (A \) or \ (B \) and can not pass at the same time.

May assume \ (f [i] \) represents the elapsed \ (I \) is the shortest.

It must have \ (F [A] + F [B] = F [T] \) .

In no hurry to deal with this formula, we first consider the handling of the whole issue.

Because any one of the shortest path through a certain \ (A \) or \ (B \) , so we might as well do any out of one of the most short-circuited.

We found that this is not a point on the path, and it is only possible to some point on the path ( in a row ) as a legitimate point right.

If we count all points but not on the path on the shortest path to the point answer to this path, it must not be missed.

Then we can open a barrel, memory \ (f [] \) values, the enumeration point on the shortest path.

First the left point \ (i \) is added to the bucket (At this point they can begin to have an impact)

For each point, find the tub \ (f [T] -f [ i] \) is added to the number of answers.

Then the right point \ (i \) of deleting (this time they will not produce contributed)

As demand \ (f \) and that some point, both sides were \ (Dijstra \) and both sides of the topology enough.

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=5e5+10;
map<int,int> MP;
vector<int> LL[N],RR[N];
int num_edge,n,m,S,T,Sum,ans;
int Dis[N][2],Vis[N],Dag[N],R[N],f[N];
int head[N<<1],Cnt[N][2],Nex[N],L[N],Rod[N];
struct Edge{int next,to,dis;} edge[N<<1];
inline void Add(int from,int to,int dis)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].dis=dis;
    edge[num_edge].to=to;
    head[from]=num_edge;
}
inline void Dijstra_For_Count(int X,int Typ)
{
    priority_queue<pair<int,int> > Q;
    Q.push(make_pair(0,X));
    memset(Vis,0,sizeof(Vis));
    memset(Nex,0,sizeof(Nex));
    Cnt[X][Typ]=1,Dis[X][Typ]=0;
    while(Q.size())
    {
        int x=Q.top().second;Q.pop();
        if(Vis[x]) continue;Vis[x]=1;
        for(int i=head[x];i;i=edge[i].next)
            if(Dis[edge[i].to][Typ]>Dis[x][Typ]+edge[i].dis)
            {
                Dis[edge[i].to][Typ]=Dis[x][Typ]+edge[i].dis;
                Cnt[edge[i].to][Typ]=Cnt[x][Typ],Nex[edge[i].to]=x;
                Q.push(make_pair(Dis[edge[i].to][Typ],edge[i].to));
            }
            else if(Dis[edge[i].to][Typ]==Dis[x][Typ]+edge[i].dis)
                    Cnt[edge[i].to][Typ]+=Cnt[x][Typ];
    }
}
inline void TopSort(int Typ)
{
    memset(Dag,0,sizeof(Dag));
    queue<int> Q;
    for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=edge[j].next)
            if(Dis[edge[j].to][Typ^1]+Dis[i][Typ]+edge[j].dis==Dis[0][T])
                Dag[edge[j].to]++;
    for(int i=1;i<=n;i++) if(!Dag[i]) Q.push(i);
    while(Q.size())
    {
        int x=Q.front();Q.pop();
        for(int i=head[x];i;i=edge[i].next)
            if(Dis[edge[i].to][Typ^1]+Dis[x][Typ]+edge[i].dis==Dis[0][T])
            {
                if(!(--Dag[edge[i].to])) Q.push(edge[i].to);
                if(!Typ) L[edge[i].to]=max(L[edge[i].to],L[x]);
                else R[edge[i].to]=min(R[edge[i].to],L[x]);
            }
    }
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
    memset(Dis,0x3f,sizeof(Dis));
    n=read(),m=read(),S=read(),T=read();
    for(int i=1,u,v,d;i<=m;i++)
        u=read(),v=read(),d=read(),Add(u,v,d),Add(v,u,d);
    Dijstra_For_Count(S,0);Dijstra_For_Count(T,1);
    if(!Cnt[T][0]) {printf("%lld\n",n*(n-1)/2);return 0;}
    for(int i=S;i;i=Nex[i]) Rod[++Sum]=i,L[i]=Sum+1,R[i]=Sum-1;
    for(int i=1;i<=n;i++) if(!L[i]&&!R[i]) L[i]=1,R[i]=Sum;
    TopSort(0);TopSort(1);
    for(int i=1;i<=n;i++)
    {
        if(Dis[i][0]+Dis[i][1]==Dis[T][0]) f[i]=Cnt[i][0]*Cnt[i][1];
        if(L[i]>R[i]) continue;LL[L[i]].push_back(i);RR[R[i]].push_back(i);
    }
    for(int i=1;i<=Sum;i++)
    {
        for(int j=0;j<(int)LL[i].size();j++) ++MP[f[LL[i][j]]];
        ans+=MP[f[T]-f[Rod[i]]];
        for(int j=0;j<(int)RR[i].size();j++) --MP[f[RR[i][j]]];
    }
    printf("%lld",ans);
}   

Guess you like

Origin www.cnblogs.com/wo-shi-zhen-de-cai/p/11823136.html