zoukankan      html  css  js  c++  java
  • FZOJ 4106 哈

    一个图上的DP啊,怪我太年轻又没看出来考试的时候直接给它爆0了?

    (f[i][j][k])表示从(i)点到(j)经过(k)条边。由于走过的边要求权值升序,不妨换个思路(不直接枚举状态),考虑直接把所有边从小到大排序然后直接枚举每条边,然后DP,注意因为要求的是经过 不多于 (c)条边的代价,而两点间的最短路径一定不会超过(n)条边所以枚举(k)的时候(1-n)就好了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int N=5009,INF=1<<30;
    int n,m,q,f[151][151][151];
    struct Edge
    {
    	int x,y,z;
    	bool operator < (const Edge &A)const
    	{
    		return z<A.z;
    	}
    }g[N];
    
    void init()
    {
    	scanf("%d %d %d",&n,&m,&q);
    	for (int i=1;i<=m;i++)
    		scanf("%d %d %d",&g[i].x,&g[i].y,&g[i].z);
    	sort(g+1,g+1+m);
    }
    
    void work()
    {
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			for (int k=0;k<=n;k++)
    				f[i][j][k]=INF;
    	for (int i=1;i<=n;i++)
    		f[i][i][0]=0;
    	for (int i=0;i<=m;i++)
    		for (int j=1;j<=n;j++)
    			for (int k=0;k<n;k++)
    				if(f[j][g[i].x][k]!=INF)
    					f[j][g[i].y][k+1]=min(f[j][g[i].y][k+1],f[j][g[i].x][k]+g[i].z);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			for (int k=1;k<=n;k++)
    				f[i][j][k]=min(f[i][j][k-1],f[i][j][k]);
    	while(q--)
    	{
    		int a,b,c;
    		scanf("%d %d %d",&a,&b,&c);
    		printf("%d
    ",f[a][b][min(c,n)]==INF?-1:f[a][b][min(c,n)]);
    	}
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    14.2.3 InnoDB Redo Log
    14.2.3 InnoDB Redo Log
    14.2.2 InnoDB Multi-Versioning InnoDB 多版本
    mysql union ,UNION RESULT
    mysql union ,UNION RESULT
    mysql 查询优化案例
    视图上无法创建索引
    视图上无法创建索引
    /etc/security/limits.conf 设置
    14.2.1 MySQL and the ACID Model
  • 原文地址:https://www.cnblogs.com/With-penguin/p/12758262.html
Copyright © 2011-2022 走看看