炸学校

Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

“小儿么小二郎,背着那炸弹炸学校,不怕那太阳晒,也不怕那风雨狂。”估计这首歌我们大家都耳熟能详了。
于是就有一群小学生们商量着炸学校。要把本市的小学的都给炸掉。于是他们商量好了一个出发点source与集合点sink。然后有无数个小学生,n-2个学校,每个小学生都从出发点出发,负责背着一个炸弹,然后把炸弹偷偷放置在一个学校里,然后返回到集合点。

由于这群小学生们还急着回去玩撸啊撸,所以他们想尽快把所有学校都炸完。这里有m条无向路,每条路都连接着u和v这两个学校,经过这条路的时间花费为t。这些小学生只能从这些路中经过。他们同时从出发点出发,他们想知道炸完所有学校并且都回到集合点的最少需要多长时间。

输入

T,表示T组测试数据。

n(3<=n<=1000),代表学校的数量(包括出发点和集合点),还有整数m(m<10^5),表示有多少条无向路。

m行,每一行的三个整数分别是u,v,t(0<=u,v, u!=v, 0<=t<=10^5)

source和sink,分别代表出发点和集合点。(0<=source,sink)。

输入数据保证可以炸毁所有学校,并且可以到达集合点。不保证没有重边。

输出:

输出

 对于第x组数据输出一行“Case #x:”,然后是一个整数表示最少需要的时间。

示例输入

1 5 5 1 0 1 1 2 3 1 3 3 4 2 2 3 4 1 4 2

示例输出

Case #1: 9

提示

 

来源

 SCFF

示例程序

    最短路问题,求a,和b到各点的最短路,存到w和q的数组中,最后w[i] + q[i]的最大值。

#include<stdio.h>
 
 #include<string.h>
 
 #include<stdlib.h>


 #define INF 9999999


 int map[1101][1101]; 
 int v[1111],num[1111];
 
 int n,m;
 
 int a,b;
 
 int w[1111],q[1110];


 void dijkstra(int s) 
 {
 
     for(int i=0;i<n;i++)
 
     {
 
         num[i] = map[s][i];
 
         v[i] = 0;
     } 
     num[s] = 0 
 ;
 

 
    for(int i=0;i<n;i++)
 
     {
 
         int min = INF,k;
 
         for(int j=0;j<n;j++)
 
         {
             if(v[j] == 0 && num[j]<min) 
             {
 
                 min = num[j];
 
                 k = j;
             } 
         }
 
         if(min == INF)
 
         {
             break; 
         }
 
         v[k] = 1;
 
         for(int j=0;j<n;j++)
 
         {
 
             if(v[j] == 0 && num[j] > num[k] + map[k][j])
 
             {
                 num[j] = num[k] + map[j][k];
             }
         } 
     }
 
     for(int i=0;i<n;i++)
 
     {
         w[i] = num[i];
     }
 }


 void dijkstra1(int s) 
 {
 
     for(int i=0;i<n;i++)
 
     {
         num[i] = map[s][i]; 
         v[i] = 0;
     } 
     num[s] = 0;
 
     for(int i=0;i<n;i++)
 
     {
       
        int min = INF,k;
 
         for(int j=0;j<n;j++)
 
         {
             if(v[j] == 0 && num[j]<min) 
             {
                 min = num[j]; 
                 k = j;
             } 

 
         }
 
         if(min == INF)
 
         {
             break;
         } 
         v[k] = 1;
 
         for(int j=0;j<n;j++)
 
         {
 
             if(v[j] == 0 && num[j] > num[k] + map[k][j])
 
             {
                 num[j] = num[k] + map[j][k];
             }
         } 
     }
 
     for(int i=0;i<n;i++)
 
     {
         q[i] = num[i];
     }
 }






 int main() 
 {
     int T; 
     int pp = 0;
 
     scanf("%d",&T);
 
     while(T--)
 
     {
         scanf("%d%d",&n,&m); 
         for(int i=0;i<n;i++)
 
         {
             for(int j=0;j<n;j++) 
             {
                 map[i][j] = INF;
             } 
             map[i][i] = 0;
         } 
         int x,y,z;
 
         for(int i=0;i<m;i++)
 
         {
             scanf("%d%d%d",&x,&y,&z); 
             if(map[x][y]>z)
 
             {
                 map[x][y] = z; 
                 map[y][x] = z;
             }
         } 
         int mm = 0;
 
         int ii;


         scanf("%d%d",&a,&b); 
         dijkstra(a);
 
         dijkstra1(b);
 
         /*for(int i=0;i<n;i++)
         {
             int tt = 0;
             if(i!=a && i!=b)
             {
                 tt = dijkstra(a,i);
             }
             w[i] = tt;
         }
         for(int i=0;i<n;i++)
         {
             int hh = 0;
             if(i!=b && i!=a)
             {
                 hh = dijkstra(i,b);
             }
             q[i] = hh;
         }*/
         int umax = 0; 
         for(int i=0;i<n;i++)
 
         {
             if(umax<(q[i]+w[i])) 
             {
                 umax = q[i]+w[i];
             }
         }


         printf("Case #%d: %d\n",++pp,umax); 
     }
 
     return 0;
 }