题意:求一个集合到另一个集合的最小路径。

思路1:直接用循环T次Dijkstra算法,从而求得最小值,但是TLE了。后来加一个添加一个新的源点,把起点与源点路径的赋值为0就可以啦。

条件:

(1)有向图。

(2)T次Dijkstra可能会超时。

 

CODE:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

const int SIZE = 1010;
const int INF = 0x3f3f3f3f;
int d[SIZE], v[SIZE];
int w[SIZE][SIZE];
int save[SIZE];
int n, m, s;


void Dijkstra(int src)
{
    int i, j;
    memset(v, 0sizeof(v));
    for(i = 0; i <= n; i++)    d[i] = (i == src)? 0:INF;        //n+1个点 
    for(i = 0; i <= n; i++)
    {
        int x, m = INF;
        for(int y = 0; y <= n; y++) if(!v[y] && m > d[y]) m = d[x=y]; //n+1个点 
        v[x] = 1;
        for(int y = 0; y <= n; y++) d[y] <?= d[x] + w[x][y];        //n+1个点 
    }
    return ;
}


void init()
{
    memset(w, INF, sizeof(w));
    memset(d, 0sizeof(d));
    memset(v, 0sizeof(v));
    memset(save, 0sizeof(save));
}


int main()
{
    while(~scanf("%d%d%d", &n, &m, &s))
    {
        init();
        while(m--)
        {
            int u, v, cost;
            scanf("%d%d%d", &u, &v, &cost);
            if(cost < w[u][v])
                w[u][v] = cost;
        }
        int T;
        scanf("%d", &T);
        for(int i = 1 ; i <= T; i++) 
        {
            scanf("%d", &save[i]);
            w[0][save[i]] = 0;        //赋值为0 
        }
        Dijkstra(0);
        if(d[s] == INF) printf("-1\n");
        else
        {
            printf("%d\n", d[s]);
        }
    }
    return 0;
}

 

思路2:建立反向图,将终点变为源点找最小值。

 

CODE:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

const int SIZE = 1010;
const int INF = 0x3f3f3f3f;
int d[SIZE], v[SIZE];
int w[SIZE][SIZE];
int save[SIZE];
int n, m, s;


void Dijkstra(int src)
{
    int i, j;
    memset(v, 0sizeof(v));
    for(i = 1; i <= n; i++)    d[i] = (i == src)? 0:INF; 
    for(i = 1; i <= n; i++)
    {
        int x, m = INF;
        for(int y = 1; y <= n; y++) if(!v[y] && m > d[y]) m = d[x=y];  
        v[x] = 1;
        for(int y = 1; y <= n; y++) d[y] <?= d[x] + w[x][y];
    }
    return ;
}


void init()
{
    memset(w, INF, sizeof(w));
    memset(d, 0sizeof(d));
    memset(v, 0sizeof(v));
    memset(save, 0sizeof(save));
}


int main()
{
    while(~scanf("%d%d%d", &n, &m, &s))
    {
        init();
        while(m--)
        {
            int u, v, cost;
            scanf("%d%d%d", &u, &v, &cost);
            if(cost < w[v][u])            //反向单向边 
                w[v][u] = cost;           //反向单向边 
        }
        int T;
        scanf("%d", &T);
        for(int i = 1 ; i <= T; i++)     scanf("%d", &save[i]);
        Dijkstra(s);
        int m = INF;
        for(int i = 1; i <= T; i++)    m <?= d[save[i]];
        if(m == INF) printf("-1\n");
        else
        {
            printf("%d\n", m);
        }
    }
    return 0;
}

 

posted on 2012-08-30 20:22  有间博客  阅读(280)  评论(0编辑  收藏  举报