Hdu 1535 Invitation Cards

 

大意:给你一个源点,让你从这里派发n个学生去其余的n-1个站点去邀请人们去CSS,然后再返回CSS,使得总的cost最小。

 

思路:

(1)过去的时候:求一次最短路,将所有的d[i]相加。

(2)回来的时候:我开始想把SPFA所有的点,然后相加,估计会超时。由于是有向边,可以用到一个巧妙的转移的方法,我们将有向边反向,由于题目保证所有的点均可到达,所以SPFA源点,然后相加可得结果。

 

CODE:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using  namespace std;

const  int SIZE =  1000001;
const  int INF =  0x3f3f3f3f;
int u[ 2*SIZE], v[ 2*SIZE], w[ 2*SIZE], next[ 2*SIZE];
int s_u[ 2*SIZE], s_v[ 2*SIZE], s_w[ 2*SIZE];
int first[SIZE], d[SIZE];
int n, m, cnt;

void init()
{
    memset(u,  0sizeof(u));
    memset(v,  0sizeof(v));
    memset(w, INF,  sizeof(w));
    memset(d,  0sizeof(d));
    memset(next,  0sizeof(next));
    memset(first, - 1sizeof(first));
    cnt =  0;
}

void spfa( int src)
{
    queue< int> q;
     bool inq[SIZE] = { 0};
     for( int i =  1; i <= n; i++) d[i] = (i == src)?  0:INF;
    q.push(src);
     while(!q.empty())
    {
         int x = q.front(); q.pop();
        inq[x] =  0;
         for( int e = first[x]; e!=- 1; e = next[e])  if(d[v[e]] > d[x]+w[e])
        {
            d[v[e]] = d[x] + w[e];
             if(!inq[v[e]])
            {
                inq[v[e]] =  1;
                q.push(v[e]);
            }
        }
    }
}

void read_graph( int u1,  int v1,  int w1)
{
    u[cnt] = u1; v[cnt] = v1; w[cnt] = w1;
    next[cnt] = first[u[cnt]];
    first[u[cnt]] = cnt;
    cnt++;
}

int main()
{
     int T;
    scanf( " %d ", &T);
     while(T--)
    {
         int ans =  0;
        init();
        scanf( " %d%d ", &n, &m);
         for( int i =  1; i <= m; i++)    scanf( " %d%d%d ", &s_u[i], &s_v[i], &s_w[i]);
         for( int i =  1; i <= m; i++) read_graph(s_u[i], s_v[i], s_w[i]);
        spfa( 1);
         for( int i =  1; i <= n; i++) ans += d[i];
        init();
         for( int i =  1; i <= m; i++) read_graph(s_v[i], s_u[i], s_w[i]);
        spfa( 1);
         for( int i =  1; i <= n; i++) ans += d[i];
        printf( " %d\n ", ans);
    }
     return  0;
}

 

 

你可能感兴趣的:(HDU)