POJ 2449 Remmarguts' Date(k短路)

来源:互联网 发布:https协议端口 编辑:程序博客网 时间:2024/06/04 19:11

Description
给出一张n个点m条边的无向图,问从s到t的路径中第k短的路径长度
Input
第一行两个整数n和m表示点数和边数,之后m行每行三个整数a,b,c表示a点和b点之间有一条权值为c的边,之后三个整数s,t,k表示求s到t的k短路
Output
输出从s到t的路径中第k短的路径长度
Sample Input
2 2
1 2 5
2 1 4
1 2 2
Sample Output
14
Solution
k短路,spfa+A*求解
设估价函数f(p)=g(p)+h(p),其中g(p)为当前从s到该点的路径长度,h(p)为该点到t的最短路(在原图的反图上以t为起点做一遍spfa可以得到),那么在bfs这张图时当终点出队列k次时g(t)即为第k短路长度
注意当s=t时需要计算k+1短路,因为s到t这条距离为0的路不算在k短路之中
Code

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;#define INF 0x3f3f3f3f#define maxn 1111#define maxm 111111struct Edge{    int to,next,c;}edge1[maxm],edge2[maxm];int head1[maxm],tot1,head2[maxn],tot2;int dis[maxn];struct node{    int to,g,f;    bool operator < (const node &a)const    {        if(a.f==f)return a.g<g;        return a.f<f;    }};void init() {    tot1=tot2=0;    memset(head1,-1,sizeof(head1));    memset(head2,-1,sizeof(head2));}void add(int u,int v,int c){    edge1[tot1].c=c;    edge1[tot1].to=v;    edge1[tot1].next=head1[u];    head1[u]=tot1++;    edge2[tot2].c=c;    edge2[tot2].to=u;    edge2[tot2].next=head2[v];    head2[v]=tot2++;}void spfa(int s,int V){    bool vis[maxn];    memset(vis,false,sizeof(vis));    queue<int>que;    for(int i=0;i<=V;i++)dis[i]=INF;    dis[s]=0;    vis[s]=true;    que.push(s);    while(!que.empty())    {        int u=que.front();        que.pop();        vis[u]=false;        for(int i=head2[u];i!=-1;i=edge2[i].next)        {            int v=edge2[i].to;            int c=edge2[i].c;            if(dis[v]>dis[u]+c)            {                dis[v]=dis[u]+c;                if(!vis[v])                {                    vis[v]=true;                    que.push(v);                }            }        }    }}int kth_length(int s,int t,int k){    node e,temp;    int cnt=0;    priority_queue<node>que;    if(s==t)k++;    if(dis[s]==INF)return -1;    e.to=s,e.g=0,e.f=dis[s];    que.push(e);    while(!que.empty())    {        e=que.top();        que.pop();        if(e.to==t)cnt++;        if(cnt==k)return e.g;        for(int i=head1[e.to];~i;i=edge1[i].next)        {            temp.to=edge1[i].to;            temp.g=e.g+edge1[i].c;            temp.f=temp.g+dis[temp.to];            que.push(temp);        }    }    return -1;}int main(){     int n,m,u,v,c,s,t,k;     while(~scanf("%d%d",&n,&m))     {        init();        while(m--)        {            scanf("%d%d%d",&u,&v,&c);            add(u,v,c);        }        scanf("%d%d%d",&s,&t,&k);        spfa(t,n);        int ans=kth_length(s,t,k);        printf("%d\n",ans);     }     return 0;}
0 0