[csu] 1175: A Tour Around Hangzhou [最短路][压缩DP][模板题]

来源:互联网 发布:数据连接池hikari 编辑:程序博客网 时间:2024/04/27 21:31

Description
swimming来到杭州旅行,杭州是个美丽的城市,有很多美丽的景点.但让他头痛的是这些景点之间都有很长的距离,swimming决定选择便宜快捷的公交作为交通工具.杭州的公交网也十分复杂,不同的景点之间要转很多次公交才能到达,已知这些公交都只能站点上下车,并且相同的两个站点之间可能会有多班公交车.swimming想让你帮他设计一条旅游线路,花最少的钱旅游完所有的景点,最后回到出发地.

Input

输入有多组案例.
对于每个案例,第一行包含3个数据,公交站点的个数n(1<=n<=10^4),公交线路数量m(1<=m<=10^5),景点数量k(k<15);接下来m行每行包括三个数据si,ei,vi(0<=si,ei < n 1 <=vi <=100)表示有一班往返于站点si和ei之间的交通线路费用为vi;接下来一行包括k个小于n的整数,表示这些站点附近有景点,swimming必须到达这些站点;最后一行包含一个小于n的整数,表示swimming的出发地.

Output

如果swimming能旅游完所有的景点并且最后回到出发地,输出swimming坐公交旅行的最低花费;如果不能,输出”What a pity”(不加引号).对于每个案例,输出占一行.

Sample Input

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

Sample Output

    9

题解

最短路+压缩DP 的模板题

#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define INF 0x3f3f3f#define MAX_N 10005#define MAX_C 15using namespace std;typedef pair<int,int> P;struct edge{int to,cost;};vector<edge> G[MAX_N];int d[MAX_N];int V,E;int dijkstra(int s,int t){    priority_queue<P,vector<P>,greater<P> > que;    que.push(P(0,s));    fill(d,d+V,INF);    d[s]=0;     while(!que.empty()){        P p=que.top();que.pop();        int c=p.first,v=p.second;//      if(v==t) return c;        if(c>d[v]) continue;        for(int i=0;i<G[v].size();i++){            edge &e=G[v][i];            int dist=c+e.cost;            if(d[e.to]>dist){                d[e.to]=dist;                que.push(P(dist,e.to));            }        }    }    return d[t];}int mp[MAX_C][MAX_C];int dp[1<<MAX_C][MAX_C];int res[MAX_C],N,se;void slove(){    for(int S=0;S<1<<N;S++) fill(dp[S],dp[S]+N,INF);    dp[(1<<N)-1][0]=0;    for(int S=(1<<N)-2;S>=0;S--)        for(int v=0;v<N;v++)            for(int u=0;u<N;u++)                if(!(S>>u&1))                    dp[S][v]=min(dp[S][v],dp[S|1<<u][u]+mp[v][u]);    if(dp[0][0]==INF) puts("What a pity");    else printf("%d\n",dp[0][0]);}int main(){    int x,y,c;    while(scanf("%d%d%d",&V,&E,&N)!=EOF){        for(int i=0;i<E;i++){            scanf("%d%d%d",&x,&y,&c);            G[x].push_back(edge{y,c});            G[y].push_back(edge{x,c});        }        for(int i=0;i<N;i++)            scanf("%d",&res[i]);        scanf("%d",&se);        bool flag=false;        for(int i=0;i<N;i++)            if(res[i]==se){                swap(res[0],res[i]);                flag=true;                break;            }        if(!flag){            swap(res[0],res[N]);            res[0]=se;            N++;        }//      for(int i=0;i<N;i++)//          printf("%d ",res[i]);        for(int i=0;i<N;i++){            for(int j=i+1;j<N;j++){                mp[i][j]=mp[j][i]=dijkstra(res[i],res[j]);        //      printf("%d\n",mp[i][j]);            }            mp[i][i]=0;        }        slove();        for(int i=0;i<V;i++)            while(!G[i].empty())                G[i].pop_back();    }    return 0;}
0 0
原创粉丝点击