zoukankan      html  css  js  c++  java
  • k短路模板+例题

    基础模板:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 1010;
    
    int n,m,x,ct;
    int g[maxn][maxn],gr[maxn][maxn],dist[maxn],vis[maxn];
    
    struct node
    {
        int id,fi,gi;
        friend bool operator < (node a,node b)
        {
            if(a.fi == b.fi)
            return a.gi > b.gi;
            return a.gi > b.gi;
        }
    }s[20000010];
    
    int init()
    {
        memset(dist,0x3f,sizeof(dist));
        for(int i = 0;i <= n;i ++)
        vis[i] = 1;
        dist[n - 1] = 0;
        for(int i = 0;i < n;i ++)
        {
            int k = n;
            for(int j = 0;j < n;j ++)
            if(vis[j] && dist[j] < dist[k])
            k = j;
            if(k == n)
            break;
            vis[k] = 0;
            for(int j = 0;j < n;j ++)
            if(vis[j] && dist[k] + gr[k][j] < dist[j])
            dist[j] = dist[k] + gr[k][j];
        }
        return 1;
    }
    
    int solve()
    {
        if(dist[0] == inf)
        return -1;
        ct = 0,s[ct].id = 0,s[ct].fi = 0;
        s[ct++].gi = dist[0];
        int cnt = 0;
        while(ct)
        {
            int id = s[0].id;
            int fi = s[0].fi;
    
            if(id == n - 1)
            cnt++;
            if(cnt == x)
            return fi;
            pop_heap(s,s + ct);
            ct--;
            for(int j = 0;j < n;j ++)
            {
                if(g[id][j] < inf)
                {
                    s[ct].id = j;
                    s[ct].fi = fi + g[id][j];
                    s[ct].gi = s[ct].fi + dist[j];
                    ct ++;
                    push_heap(s,s + ct);
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        while(cin >> n >> m >> x)
        {
            memset(g,0x3f,sizeof(g));
            memset(gr,0x3f,sizeof(gr));
    
            for(int i = 0;i < m;i ++)
            {
                int p,q,r;
                cin >> p >> q >> r;
                p--;
                q--;
                g[p][q] = g[p][q] <= r ? g[p][q] : r;
                gr[q][p] = gr[q][p] <= r ? gr[q][p] : r;
            }
            init();
            cout << solve() << endl;
        }
        return 0;
    }
    

    例:

    2 2 2
    1 2 5
    2 1 4
    14

    例题1:poj2449 Remmarguts' Date

    。。。。。

    Input

    The first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000). Stations are numbered from 1 to N. Each of the following M lines contains three integer numbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directed sideway from A-th station to B-th station with time T.

    The last line consists of three integer numbers S, T and K (1 <= S, T <= N, 1 <= K <= 1000).

    Output

    A single line consisting of a single integer number: the length (time required) to welcome Princess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you should output "-1" (without quotes) instead.

    Sample Input

    2 2
    1 2 5
    2 1 4
    1 2 2
    

    Sample Output

    14

    题意:求两点间的第K短路(A*算法模板)(摘自此处

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define inf 1<<29
    #define M 500200
    #define N 500020
    using namespace std;
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n,m,k,s,t;
    int head[N],pos;
    int head1[N],pos1;
    struct edge{int to,c,next;}ee[M<<1],e[M<<1];
    void add(int a,int b,int c)
    {pos++;e[pos].to=b,e[pos].c=c,e[pos].next=head[a],head[a]=pos;}
    void add1(int b,int a,int c)
    {pos1++;ee[pos1].to=b,ee[pos1].c=c,ee[pos1].next=head1[a],head1[a]=pos1;}
    queue<int>Q;bool vis[N];int dis[N];
    void spfa(int st)
    {
    	for(int i=1;i<=n;i++)
    		dis[i]=inf,vis[i]=0;
    	dis[st]=0,vis[st]=1;Q.push(st);
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();vis[u]=0;
    		for(int i=head1[u];i;i=ee[i].next)
    		{
    			int v=ee[i].to;
    			if(dis[v]>dis[u]+ee[i].c)
    			{
    				dis[v]=dis[u]+ee[i].c;
    				if(!vis[v])Q.push(v),vis[v]=1;
    			}
    		}
    	}
    }
    struct node{int x,d,f;}u,v;
    bool operator < (node a,node b)
    {
    	if(a.f!=b.f)return a.f>b.f;
    }
    priority_queue<node>que;
    void solve()
    {
    	while(!que.empty())que.pop();
    	if(dis[s]==inf)
    	{
    		printf("-1
    ");	
    		return ;
    	}
    	u.f=dis[s],u.x=s,u.d=0;
    	int now=0;que.push(u);
    	while(!que.empty())
    	{
    		u=que.top();que.pop();
    		if(u.x==t)
    			now++;
    		if(now==k)
    		{
    			printf("%d
    ",u.d);
    			return;
    		}
    		for(int i=head[u.x];i;i=e[i].next)
    		{
    			int tc=e[i].to;v=u;
    			v.x=tc,v.d+=e[i].c;
    			v.f=dis[v.x]+v.d;
    			que.push(v);
    		}
    	}printf("-1
    ");
    }
    int main()
    {
    //	freopen("a.in","r",stdin);
    //	freopen("a.out","w",stdout);
    	while(~scanf("%d%d",&n,&m))
    	{
    		memset(head,0,sizeof(head));
    		memset(head1,0,sizeof(head1));
    		pos1=pos=0;
    		for(int i=1;i<=m;i++)
    		{
    			int x=read(),y=read();
    			int c=read();
    			add(x,y,c);
    			add1(x,y,c);
    		}s=read(),t=read(),k=read();
    		if(s==t)k++;
    		spfa(t);solve();
    	}
    }

    例题2:ACM-ICPC 2018 沈阳赛区网络预赛 Made In Heaven

    。。。。。。。

    Input

    There are at most 505050 test cases.

    The first line contains two integers NNN and MMM (1≤N≤1000,0≤M≤10000)(1 leq N leq 1000, 0 leq M leq 10000)(1≤N≤1000,0≤M≤10000). Stations are numbered from 111 to NNN.

    The second line contains four numbers S,E,KS, E, KS,E,K and TTT ( 1≤S,E≤N1 leq S,E leq N1≤S,E≤N, S≠ES eq ES≠E, 1≤K≤100001 leq K leq 100001≤K≤10000, 1≤T≤1000000001 leq T leq 1000000001≤T≤100000000 ).

    Then MMM lines follows, each line containing three numbers U,VU, VU,V and WWW (1≤U,V≤N,1≤W≤1000)(1 leq U,V leq N, 1 leq W leq 1000)(1≤U,V≤N,1≤W≤1000) . It shows that there is a directed road from UUU-th spot to VVV-th spot with time WWW.

    It is guaranteed that for any two spots there will be only one directed road from spot AAA to spot BBB (1≤A,B≤N,A≠B)(1 leq A,B leq N, A eq B)(1≤A,B≤N,A≠B), but it is possible that both directed road <A,B><A,B><A,B> and directed road <B,A><B,A><B,A> exist.

    All the test cases are generated randomly.

    Output

    One line containing a sentence. If it is possible for JOJO to arrive at the destination in time, output "yareyaredawa" (without quote), else output "Whitesnake!" (without quote).

    样例输入

    2 2
    1 2 2 14
    1 2 5
    2 1 4

    样例输出

    yareyaredawa

    略有改动:

    代码如下

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    #define N 1100
    #define M 100010
    #define inf 1000000000
    int num1=0,num2=0,n,m,s,t,k,h1[N],h2[N],d[N],flag[N];
    struct node1
    {
        int x,y,z,next;
    }mp1[M],mp2[M];
    struct node{
        int v,c;
        node(int vv,int cc) : v(vv),c(cc){}
        friend bool operator < (node x,node y)
        {
            return x.c+d[x.v]>y.c+d[y.v];
        }
    };
    void insert1(int x,int y,int z)
    {
        mp1[++num1].x=x;
        mp1[num1].y=y;
        mp1[num1].z=z;
        mp1[num1].next=h1[x];
        h1[x]=num1;
    }
    void insert2(int x,int y,int z)
    {
        mp2[++num2].x=x;
        mp2[num2].y=y;
        mp2[num2].z=z;
        mp2[num2].next=h2[x];
        h2[x]=num2;
    }
    void spfa()
    {
        queue<int>Q;
        Q.push(t);
        for(int i=1;i<=n;i++) 
            d[i]=inf;
        d[t]=0;
        memset(flag,0,sizeof(flag));
        flag[t]=1;
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();
            flag[u]=0;
            for(int i=h1[u];i;i=mp1[i].next)
            {
                int v=mp1[i].y;
                if(d[v]>d[u]+mp1[i].z)
                {
                    d[v]=d[u]+mp1[i].z;
                    if(!flag[v])
                    {
                        flag[v]=1;
                        Q.push(v);
                    }
                }
            }
        }
    }
    int astar()
    {
        if(d[s]==inf) 
            return -1;
        priority_queue<node>p;
        int cnt=0;
        p.push(node(s,0));
        while(!p.empty())
        {
            node u=p.top();p.pop();
            if(u.v==t)
            {
                cnt++;
                if(cnt==k) 
                    return u.c;
            }
            for(int i=h2[u.v];i;i=mp2[i].next)
            {
                int y=mp2[i].y;
                p.push(node(y,u.c+mp2[i].z));
            }
        }
        return -1;
    }
    int main()
    {
        int w;
        while(scanf("%d%d",&n,&m)>0)
        {
            scanf("%d%d%d%d",&s,&t,&k,&w);
            memset(h1,0,sizeof(h1));
            num1=0;
            memset(h2,0,sizeof(h2));
            num2=0;
            for(int i=1;i<=m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                insert1(y,x,z);
                insert2(x,y,z);
            }
            spfa();
            int va = astar();
            if(va == -1 || va > w)
            printf("Whitesnake!
    ");
            else
            printf("yareyaredawa
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    数论-FTT 和 NTT
    数论-FFT高精度乘法
    树链剖分-模板题 HAOI2015
    图论-最小生成树模板
    图论-次短路求法
    图论-某图论专练 Round3 (April, 2018)
    动规-某动规专练 Round1 (April, 2018)
    动规-某动规专练 Round2 (April, 2018)
    Java IO: 并发IO
    Java IO: Reader And Writer
  • 原文地址:https://www.cnblogs.com/lu1nacy/p/10016633.html
Copyright © 2011-2022 走看看