Luo Gu P1629 postman messenger

The judge things more inside

In fact you do not need so much data to the very water

What can add weight from side ring

This question completely and violence do n times dij (3 * 10 ^ 7 more dangerous)

More optimal method is:

Dij first pass calculates the distance to each local postman

The second pass reverse side construction, is easy to see the postman transverse distance to each place is to place each distance postman

This approach can be put into a single shortest path to the end of single-source shortest path

Stated otherwise, since run twice Dij, in order to facilitate the distinction write separate variable names and finally 1 is the first dij related to 2 is the second dij

The Code

#include<iostream>
#include<cmath>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

int n,m;
int h1[1926],h2[1926];   
int s1,s2;
struct edge{
    int next,to,dis;
};
int v1[1926],v2[1926];
int d1[1926],d2[1926];
edge e1[200860],e2[200860];
int looker1[1020][1020];   //looker是得到i,j边距离最小值 
int looker2[1020][1020];
int l1[1020][1020];   //l1是标记i,j是否走过 
int l2[1020][1020];

void addedge1(int next,int to,int dis)
{
    e1[++s1].dis=dis;
    e1[s1].next=h1[next];
    e1[s1].to=to;
    h1[next]=s1;
}

void addedge2(int next,int to,int dis)
{
    e2[++s2].dis=dis;
    e2[s2].to=to;
    e2[s2].next=h2[next];
    h2[next]=s2;
}

void dij1(int start)
{
    priority_queue <pair<int,int> > q;   //pair的用法 
    memset(d1,0x3f,sizeof(d1));
    memset(v1,0,sizeof(v1));
    q.push(make_pair(0,start));
    d1[1]=0;
    while(!q.empty())
    {
        int i,j,k;
        int t=q.top().second;
        q.pop();
        if(v1[t]) continue;
        v1[t]=1;  
        for(i=h1[t];i;i=e1[i].next)
        {
            j=e1[i].to;
            if(l1[t][j]) continue;  //l1是判断t和j边是否走过一次,如果走过了还能走由Dij性质得到有重边 
            L1 [T] [J] = . 1 ; 
            K = looker1 [T] [J];
             IF (D1 [T] + K < D1 [J]) 
            { 
                D1 [J] = D1 [T] + K; 
                q.push (the make_pair ( - ; D1 [J], J))
                  // pair is ascending the first data, it is necessary to take opposite number
                 // after 5 e.g. greater than 3, 5 so that the first team, but take opposite number with the big -3 5 
            } 
        } 
    } 
} 

void dij2 ( int Start) 
{     
    the priority_queue <pair < int , int >> Q; 
    Memset (D2,0x3F , the sizeof (D2));   // as the initial value for the minimum it is assigned a maximum value 
    Memset (V2, 0 , the sizeof (V2)); 
    q.push (the make_pair ( 0 , Start)); 
    D2 [ . 1 ] = 0 ;
     the while (! q.empty ()) 
    { 
        int I, J, K;
         int T = q.top () SECOND;. 
        q.pop (); 
        IF (V2 [T]) Continue ; 
        
        V2 [T] = . 1 ;
         for (I = H2 [T]; I; I = E2 [I] .next) 
        { 
            J =e2[i].to;
            k=looker2[t][j];
            if(l2[t][j]) continue;
            l2[t][j]=1;
            if(d2[t]+k<d2[j])
            {
                d2[j]=d2[t]+k;
                q.push(make_pair(-d2[j],j));
            }
        }
    }
}

int main()
{
    int i,j;
    scanf("%d %d",&n,&m);
    memset(looker1,0x3f,sizeof(looker1));
    memset(looker2,0x3f,sizeof(looker2));
    for(i=1;i<=m;i++)
    {
        int t1,t2,t3;
        scanf("%d %d %d",&t1,&t2,&t3);
        looker1[t1][t2]=min(looker1[t1][t2],t3);  //得到 t1,t2的最小值 
        looker2[t2][t1]=min(looker2[t2][t1],t3);
        addedge1(t1,t2,t3);
        addedge2(t2,t1,t3);  //反向建图 
    }
    int tot=0;
    dij1(1);
    dij2(1);
    for(i=1;i<=n;i++)
    {
        tot+=d1[i]+d2[i];
    }
    printf("%d",tot);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zsx6/p/11059345.html