ACM-ICPC 2018 南京赛区网络赛 L题 K短路

#include <bits/stdc++.h>

using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e5+7;

int n,m,k;

bool vis[MAXN];
long long dist[MAXN][11];

struct qnode{
    int v;
    int c;
    qnode(){}
    qnode(int _v, int _c):v(_v),c(_c){}
    bool operator <(const qnode &a)const{
        return c > a.c;
    }
};

vector<qnode> g[MAXN];

void Dijstra(){
    for(int i=1; i<=n; ++i){
        for(int j=0; j<=k; ++j){
            if(i==1) dist[i][j] = 0;
            else dist[i][j] = INF;
        }
    }

    priority_queue<qnode> pq[11];
    for(int i=0; i<=k; ++i){
        memset(vis, false, sizeof(vis));
        pq[i].push(qnode(1, 0));
        qnode tmp;
        while(!pq[i].empty()){
            tmp = pq[i].top();
            pq[i].pop();
            int u = tmp.v;
            if(vis[u]) continue;
            vis[u] = true;
            for(int j=0; j<g[u].size(); ++j){
                int v = g[u][j].v;
                int cost = g[u][j].c;
                if(i==0){
                    if(!vis[v]&&dist[v][i]>dist[u][i]+cost){
                        dist[v][i] = dist[u][i] + cost;
                        pq[i].push(qnode(v,dist[v][i]));
                    }
                }else{
                    if(!vis[v]){
                        //d[v][i] 从1到v恰好去掉i条边
                       //去掉uv边或松弛操作
                        long long tmp=min(dist[u][i-1],dist[u][i]+cost);
                        if(dist[v][i]>tmp)
                        {
                            dist[v][i] = min(dist[v][i], tmp);
                            pq[i].push(qnode(v,dist[v][i]));
                        }
                    }
                }
            }
        }
    }

}


int main(int argc, char const *argv[])
{
    int t;
    freopen("in.txt","r",stdin);

    scanf("%d",&t);
    while(t--){
        for(int i=0; i<MAXN; ++i) g[i].clear();
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<m; ++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            g[u].push_back(qnode(v,w));
        }

        Dijstra(); 
        cout<<dist[n][k]<<endl;
    }
    return 0;
}
#include <bits/stdc++.h>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5+7;
#define LL long long
struct nod{
    int v;LL c;
    nod(int v=0,LL c=0):v(v),c(c){}
    bool operator <(const nod&a)const{
        return c>a.c;
    }
};

struct edge{
    int v,c;
    edge(int v=0,int c=0):v(v),c(c){}
};
vector<edge> e[maxn*11];
void addedge(int a,int b,int c)
{
    e[a].push_back(edge(b,c));
//    printf("add %d %d %d\n",a,b,c);
}
LL d[maxn*12];
bool vis[maxn*12];

int n,m,k;
LL dij()
{
    for(int i=0,sz=n*(k+1)+k;i<=sz;i++)
    {
        vis[i]=false;
        d[i]=INF;
    }
    priority_queue<nod>q;
    for(int i=0;i<=k;i++)
    {
        d[k+1+i]=0;
    }
    q.push(nod(k+1,0));
    nod t;
    while(!q.empty())
    {
        t=q.top();q.pop();
        int u=t.v;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=0,sz=e[u].size();i<sz;i++)
        {
            int v=e[u][i].v,c=e[u][i].c;
            if(!vis[v]&&d[v]>d[u]+c){
                d[v]=d[u]+c;
                q.push(nod(v,d[v]));
            }
        }
    }
    LL ans=1e18;
    for(int i=0;i<=k;i++)
        ans=min(ans,d[n*(k+1)+i]);
    return ans;
}
int main()
{
   // freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        while(m--)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
//            printf("%d %d %d\n",a,b,c);
            a*=k+1;b*=k+1;
            for(int i=0;i<=k;i++)
            {
                addedge(a+i,b+i,c); 
//a0 b0 c
//a0 b1 0
//...
//ak-1 bk-1 c
//ak-1 bk 0
                addedge(a+i,b+i+1,0);
            }
            e[a+k].pop_back();

        }
        printf("%lld\n",dij());
        for(int i=1;i<=n;i++)
            for(int j=0;j<=k;j++)
            e[i*(k+1)+j].clear();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/polya/p/9711033.html