zoukankan      html  css  js  c++  java
  • [TJOI2019]大中锋的游乐场——最短路+DP

    题目链接:

    [TJOI2019]大中锋的游乐场

    题目本质要求的还是最短路,但因为有第二维权值(汽水看成$+1$,汉堡看成$-1$)的限制,我们在最短路的基础上加上一维$f[i][j]$表示到达$i$节点,权值为$j$的最短路长度,然后像正常最短路那样转移,最后取终点所有状态的最小值即可。

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<bitset>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct lty
    {
    	int val,node,num;
    	lty(int a,int b,int c){val=a,node=b,num=c;}	
    };
    bool operator <(lty x,lty y){return x.val>y.val;}
    int f[10010][30];
    int head[10010];
    int val[200010];
    int v[10010];
    int to[200010];
    int next[200010];
    int n,m,k;
    int T;
    int tot;
    int a,b;
    int x,y,z;
    int vis[10010][30];
    priority_queue<lty>q;
    void add(int x,int y,int z)
    {
    	next[++tot]=head[x];
    	head[x]=tot;
    	to[tot]=y;
    	val[tot]=z;
    }
    void init()
    {
    	memset(vis,0,sizeof(vis));
    	memset(head,0,sizeof(head));
    	tot=0;
    }
    void dijkstra(int S,int T)
    {
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=0;j<=2*k;j++)
    		{
    			f[i][j]=1<<30;
    		}
    	}
    	f[S][k+v[S]]=0;
    	q.push(lty(f[S][k+v[S]],S,k+v[S]));
    	while(!q.empty())
    	{
    		lty now=q.top();
    		q.pop();
    		if(vis[now.node][now.num])
    		{
    			continue;
    		}
    		vis[now.node][now.num]=1;
    		for(int i=head[now.node];i;i=next[i])
    		{
    			if(now.num+v[to[i]]<0||now.num+v[to[i]]>2*k)continue;
    			if(f[to[i]][now.num+v[to[i]]]>f[now.node][now.num]+val[i])
    			{
    				f[to[i]][now.num+v[to[i]]]=f[now.node][now.num]+val[i];
    				q.push(lty(f[to[i]][now.num+v[to[i]]],to[i],now.num+v[to[i]]));
    			}
    		}
    	}
    	int ans=1<<30;
    	for(int i=0;i<=2*k;i++)
    	{
    		ans=min(ans,f[T][i]);
    	}
    	printf("%d",ans==(1<<30)?-1:ans);
    }
    void solve()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&v[i]);
    		if(v[i]==2)
    		{
    			v[i]=-1;
    		}
    	}
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	scanf("%d%d",&a,&b);
    	dijkstra(a,b);
    }
    int main()
    {
    	scanf("%d",&T);
    	while(T--)
    	{
    		init();
    		solve();
    	}
    }
  • 相关阅读:
    一个zip压缩类,欢迎吐槽
    Java 基本数据类型
    《C++游戏开发》笔记十二 战争迷雾:初步实现
    Java蓝桥杯 算法提高 九宫格
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 队列操作
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10835688.html
Copyright © 2011-2022 走看看