uva 11280 状态压缩+最短路

来源:互联网 发布:有钱人的生活知乎 编辑:程序博客网 时间:2024/06/17 06:25

题意:坐飞机从 a 地到 b 地 ,在最多停留s次时 , 最小花费是多少?

在题目给出的地点 , 是按从远到近给出的 , 并且给出的航班中 , 不会有从远地点到近地点的航班。

因此从这可以看出 , 题目给的图是一个DAG图 , 那么我们就能用toposort来找最短路。


注意: 会有重边


解法:


构造一个数组 d[i][j]  , 表示从开始点 s  到点 i , 在停留 j 次时的最小花费。

然后我们再求出这个图的toposort , 再求这个每一个点和其相邻点的距离。


代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <vector>#include <queue>#include <map>using namespace std;#define maxn 110#define INF 0xfffffffint grap[maxn][maxn] ;long long d[maxn][maxn];int n , m;int s1 , t1;int s;int index1[maxn];  //存储每个点的入度int topo[maxn];void init(){    memset(grap , -1 , sizeof(grap));    memset(index1 , 0 , sizeof(index1));    s1 = 0 , t1 = n-1;    s = n-2;}//可能会有重边void add_edge(int x , int y , int z){    if(grap[x][y] == -1)    {        grap[x][y] = z;        index1[y] += 1;    }    else if(grap[x][y] > z)        grap[x][y] = z;}void toposort(){    int i , u;    int l = 0 , r = 0;    for(i = 0; i < n; i++)        if(index1[i] == 0)  topo[r++] = i;    while(l < r)    {        u = topo[l++];        for(i = 0; i < n; i++)            if(grap[u][i] != -1 && index1[i] > 0)            {                index1[i]--;                if(index1[i] == 0)                    topo[r++] = i;            }    }}void spfa(){    int i , j;    int u , v;    for(i = 0; i < n; i++)        for(j = 0; j <= s; j++)            d[i][j] = INF;    for(i = 0; i < n; i++)        if(grap[s1][i] != -1)            d[i][0] = grap[s1][i];    j = 1;    while(j < n)    {        u = topo[j];        for(v = 0; v < s; v++)        {            if(d[u][v] == INF)  continue;            for(i = 0; i < n; i++)                if(grap[u][i] != -1)                {                    if(d[i][v+1] > d[u][v]+grap[u][i])                    {                        d[i][v+1] = d[u][v]+grap[u][i];                    }                }        }        j++;    }}int main(){    //用map来区分每个点    //cout<<INF<<endl;    int t , cas = 1;    scanf("%d" , &t);    while(t--)    {        scanf("%d" , &n);        init();        map<string , int>ma;        char city[30] , city2[30];        int i , x , y , z;        for(i = 0; i < n; i++)        {            scanf("%s" , city);            ma[city] = i;        }        map<string,int>::iterator it;        scanf("%d" , &m);        for(i = 0; i < m ; i++)        {            scanf("%s %s %d" , city , city2 , &z);            it=ma.find(city);            x = it->second;            it=ma.find(city2);            y = it->second;            add_edge(x , y , z);        }        int q;        toposort();        spfa();        for(i = 1; i <= s; i++)            d[t1][i]  = min(d[t1][i] , d[t1][i-1]);        scanf("%d" , &q);        printf("Scenario #%d\n" , cas++);        for(i = 0; i < q; i++)        {            scanf("%d" , &x);            x = x>s?s:x;            if(d[t1][x] == INF)  cout<<"No satisfactory flights"<<endl;            else  cout<<"Total cost of flight(s) is $"<<d[t1][x]<<endl;        }        if(t) cout<<endl;    }    return 0;}/*24CalgaryWinnipegOttawaFredericton7Calgary Ottawa 350Calgary Winnipeg 125Calgary Ottawa 300Winnipeg Fredericton 325Winnipeg Ottawa 100Calgary Fredericton 875Ottawa Fredericton 1753 2 1 03CalgaryMontrealFredericton2Calgary Montreal 300Montreal Fredericton 3251 0*/


0 0
原创粉丝点击