现在的位置: 首页 > 综合 > 正文

hdu 1535 Invitation Cards(spfa)

2017年10月18日 ⁄ 综合 ⁄ 共 1580字 ⁄ 字号 评论关闭

小记:这题还是要理解了题意就好做了,这题之前做过一次。

题意:从一点送请柬到其它n-1个点,然后再回来的最小路程。

思路:去送的最小路程就是单源最短路径,

而回来,想一下就可以知道,因为图是有向图,所以将图反向之后,那么我到其它n-1个点的最短路径就是他们到我的最短路径了。

因此反向一次在进行一次spfa,将总共两次的spfa的最短距离相加起来就是answer了。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8
#define DEBUG printf("here\n");

const int MAX_ = 1000010;
const int N = 100010;
const int INF = 0x7fffffff;

int n;

struct node{
    int u, v;
    int cap, next;
}edge[MAX_*2];

struct point{
    int x,y,cap;
}p[MAX_];

int H[MAX_*2];
//int V[MAX_*2];
int d[MAX_];
bool vis[MAX_];
int m, cnt, M;

void add(int u, int v, int cap)
{
    edge[M].u = u;
    edge[M].v = v;
    edge[M].cap = cap;
    edge[M].next = H[u];
    H[u] = M++;
}

void spfa(int start)
{
    queue<int > q;
    REP(i, 0, n+1){
        vis[i] = 0;
        d[i] = INF;
    }
    vis[start] = 1;
    d[start] = 0;
    q.push(start);

    while(!q.empty()){
        int cur = q.front(); q.pop();

        vis[cur] = 0;

        for(int i = H[cur]; i+1; i = edge[i].next){
            int v = edge[i].v;
            int u = edge[i].u;
            if(d[v] > d[u] + edge[i].cap){
                d[v] = d[u] + edge[i].cap;
                if(!vis[v]){
                    vis[v] = 1;
                    q.push(v);

                }
            }
        }

    }

    return ;
}


int main(){
	int T, ss, tt, v, s, t;
	char str[10];
	scanf("%d", &T);

	while(T-- && scanf("%d%d", &n, &m)){
	    //scanf("%d", &m);

        //mst(g, -1);

        mst(H, -1);
        //mst(V, -1);

        M = 0;
        REP(i, 0, m){
            scanf("%d%d%d", &s, &t, &v);
            add(s,t,v);
            p[i].x = s;
            p[i].y = t;
            p[i].cap = v;
        }
        spfa(1);
        int sum = 0;
        REP(i, 1, n+1){
            sum += d[i];
        }

        mst(H, -1);
        //mst(V, -1);
        M = 0;
        REP(i, 0, m){
            add(p[i].y, p[i].x, p[i].cap);
        }

        spfa(1);
        REP(i, 1, n+1){
            sum += d[i];
        }
/*
        REP(i, 0, n)REP(j, 0, n){
            printf("%.3f ", g[i][j]);
            if(j == n-1)printf("\n");
        }*/

        printf("%d\n", sum);



	}
	return 0;
}

抱歉!评论已关闭.