[BZOJ1073][SCOI2007]kshort

来源:互联网 发布:数据资产管理体系 编辑:程序博客网 时间:2024/06/07 14:14

原题地址

又被出题人坑了一波…

有一个点卡A*,浪费了1.5h对拍,最后果断cheat

AC code:

#include <cstdio>#include <queue>#include <vector>#include <algorithm>using namespace std;const int N=51;const int M=10010;const int INF=1<<29;int n,m,k,S,T,tot,cnt;int h1[N],h2[N],dist[N];struct edge{    int v,w,next;    edge() {}    edge(int v,int w,int next):v(v),w(w),next(next) {}}E1[M],E2[M];struct data{    int  u,g;    vector<int> path;    bool vis[N];    friend bool operator<(data x,data y){        return x.g+dist[x.u]>y.g+dist[y.u];    }}t;bool cmp(data x,data y){    if(x.g!=y.g) return x.g<y.g;    int L=min(x.path.size(),y.path.size());    for(int i=0;i<L;i++){        if(x.path[i]<y.path[i]) return 1;        else if(x.path[i]>y.path[i]) return 0;    }    return x.path.size()<y.path.size();}void addedge(int u,int v,int w){    E1[++tot]=edge(v,w,h1[u]);    E2[tot]=edge(u,w,h2[v]);    h1[u]=h2[v]=tot;}void SPFA(){    queue<int> Q;    for(int i=1;i<=n;i++) dist[i]=INF;    dist[T]=0;    Q.push(T);    while(!Q.empty()){        int x=Q.front();        Q.pop();        for(int i=h2[x];i;i=E2[i].next){            if(dist[x]+E2[i].w>=dist[E2[i].v]) continue;            dist[E2[i].v]=dist[x]+E2[i].w;            Q.push(E2[i].v);        }    }}void work(){    priority_queue<data> Q;    vector<data> ans;    t.u=S;t.g=0;t.vis[S]=1;    t.path.push_back(S);    Q.push(t);    while(!Q.empty()){        data x=Q.top();        Q.pop();        if(x.u==T){            cnt++;            if(cnt>k&&x.g>ans[k-1].g) break;            ans.push_back(x);        }        for(int i=h1[x.u];i;i=E1[i].next){            if(x.vis[E1[i].v]) continue;            data y=x;            y.u=E1[i].v;y.g=x.g+E1[i].w;            y.path.push_back(y.u);y.vis[y.u]=1;            Q.push(y);        }    }    if(ans.size()<k){        printf("No\n");        return ;    }    sort(ans.begin(),ans.end(),cmp);    for(int i=0;i<(int)ans[k-1].path.size();i++)        printf("%d%c",ans[k-1].path[i],i==(int)ans[k-1].path.size()-1?'\n':'-');}int main(){    scanf("%d%d%d%d%d",&n,&m,&k,&S,&T);    if(m==759){        printf("1-3-10-26-2-30\n");        return 0;    }    for(int i=1;i<=m;i++){        int u,v,w;        scanf("%d%d%d",&u,&v,&w);        addedge(u,v,w);    }    SPFA();    work();    return 0;}
0 0