2009-11-28 22:03:58來源不明

TOI 2008 4. 地道問題 (修正版II)

作法 : 仍是SPFA

但是為了不使用內建與鏈結串鏈  當初使用快排去做排序

後來發現  若使用merge sort會比較穩定

可能是快排退化了吧...

速度達到極致 8ms 不用case第五筆

順便也做出了

"

若所給通道資料無法由
侍衛休息室通到某一間房間,請輸出0。

                          "

/***********************************************************/

#include<stdlib.h>
#include<stdio.h>
#define MAX 1000000001
int min(int x,int y)
{
     if(x>=y) return y;
     else return x;
}
int input()     
{     
  char cha;     
  int x=0;     
  while(cha=getchar())     
     if(cha!=' '&&cha!='\n') break;     
  x=cha-48;     
  while(cha=getchar())      
    {     
     if(cha==' '||cha=='\n') break;     
      x=x*10+cha-48;     
    }     
    return x;     
}
int ptime[10002]={0},SP[10002]={0};
int data[1000000][3];
long long SUM;
short Queue[5000000];
int SPFA(int S,int N)  
{  
   int Dis[10002]={0};  
   int top=-1,a,b,c,used[10002]={0};  
   for(a=1;a<=N;a++)  
      Dis[a]=MAX;  
   for(a=SP[S],b=0;b<ptime[S];a++,b++)  
     {  
      Dis[data[a][1]]=min(Dis[data[a][1]],data[a][2]);  
      if(used[data[a][1]]==0)  
            Queue[++top]=data[a][1],used[data[a][1]]=1;  
     }
   Dis[S]=0;  
   for(a=0;a<=top;a++)  
      {  
         int Qp=Queue[a];  
         used[Qp]=0;  
         for(b=SP[Qp],c=0;c<ptime[Qp];b++,c++)  
            if(Dis[data[b][1]]>Dis[Qp]+data[b][2])  
              {  
                 Dis[data[b][1]]=Dis[Qp]+data[b][2];  
                 if(used[data[b][1]]==0)  
                   Queue[++top]=data[b][1],used[data[b][1]]=1;  
              }
      }  
      for(a=1;a<=N;a++)
        if(Dis[a]==MAX)  return 1;
        else   SUM+=Dis[a];
   return 0;
}
int MergeSort(int,int);
int Merge(int,int,int);
main()
{
  int N,M;
  while(scanf("%d %d",&M,&N)==2)
     {
        int a,b,c,d,x,y,Flag=0;
        for(a=0;a<N;a++)
           {
             x=input(),y=input(),d=input(); 
             data[a][0]=x,data[a][1]=y,data[a][2]=d;
             ptime[x]++;
           }
        MergeSort(0,N-1);
        for(a=1;a<=M;a++)    SP[a]=MAX;
        for(a=0;a<N;a++)
            SP[data[a][0]]=min(a,SP[data[a][0]]);
        SUM=0;
        Flag=SPFA(1,M);
        for(a=1;a<=M;a++)    SP[a]=MAX,ptime[a]=0;
        for(a=0;a<N;a++)
            b=data[a][0],data[a][0]=data[a][1],data[a][1]=b,ptime[data[a][0]]++;
        if(Flag==1) {printf("0\n");continue;}
        MergeSort(0,N-1);
        for(a=0;a<N;a++)
            SP[data[a][0]]=min(a,SP[data[a][0]]);
       
        Flag=SPFA(1,M);
        if(Flag==1) printf("0\n");
        else
            printf("%lld\n",SUM);
        for(a=1;a<=M;a++)
           ptime[a]=0;
     }
  return 0;
}
int MergeSort(int l,int h)
{
   if(l<h)
      {
         int m=(l+h)/2;
         MergeSort(l,m);
         MergeSort(m+1,h);
         Merge(l,m,h);
      }
}
int x[100001][3];
int Merge(int l,int m,int h)
{
   int in1=l,in2=m+1,out=l;
   int top=0,a,b;
   while(in1<=m&&in2<=h)
      if(data[in1][0]>data[in2][0])
           x[top][2]=data[in2][2],x[top][1]=data[in2][1],x[top++][0]=data[in2++][0];
      else
           x[top][2]=data[in1][2],x[top][1]=data[in1][1],x[top++][0]=data[in1++][0];
   while(in1<=m)
       x[top][2]=data[in1][2],x[top][1]=data[in1][1],x[top++][0]=data[in1++][0];
   while(in2<=h)
       x[top][2]=data[in2][2],x[top][1]=data[in2][1],x[top++][0]=data[in2++][0];
   for(a=l,b=0;a<=h;a++,b++)
      data[a][0]=x[b][0],data[a][1]=x[b][1],data[a][2]=x[b][2];
}
/*
3 9
1 1 8
2 3 47
2 1 42
2 2 24
2 1 5
2 2 3
3 1 46
3 1 15
2 3 24
*/