• bzoj1003:[ZJOI2006]物流运输


    传送门

    开始刷第一版的题,一个dp+最短路的题,不算太难
    设出状态(f[i])表示当前到第(i)天的最小成本
    由于变更路线是要花钱的,那么转移考虑上一次变更道路的位置就好了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=1010;
    int dis[30],cnt,n,m,k,e,d,f[110],pre[maxn],nxt[maxn],h[21],v[maxn];
    bool vis[30],used[30],g[30][110];
    queue<int>q;
    void add(int x,int y,int z)
    {
    	pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt,v[cnt]=z;
    	pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt,v[cnt]=z;
    }
    void spfa()
    {
    	memset(dis,63,sizeof dis);q.push(1),dis[1]=0;
    	while(!q.empty())
    	{
    		int x=q.front();q.pop();vis[x]=0;
    		for(rg int i=h[x];i;i=nxt[i])
    			if(!used[pre[i]]&&dis[pre[i]]>dis[x]+v[i])
    			{
    				dis[pre[i]]=dis[x]+v[i];
    				if(!vis[pre[i]])vis[pre[i]]=1,q.push(pre[i]);
    			}
    	}
    }
    int main()
    {
    	read(n),read(m),read(k),read(e);
    	for(rg int i=1,x,y,z;i<=e;i++)read(x),read(y),read(z),add(x,y,z);
    	read(d);
    	for(rg int i=1,p,x,y;i<=d;i++)
    	{
    		read(p),read(x),read(y);
    		for(rg int j=x;j<=y;j++)g[p][j]=1;
    	}
    	memset(f,63,sizeof f);f[0]=0;
    	for(rg int i=1;i<=n;i++)
    	{
    		memset(used,0,sizeof used);
    		for(rg int j=i;j;j--)
    		{
    			for(rg int k=1;k<=m;k++)used[k]|=g[k][j];
    			spfa();if(dis[m]>1e9)break;
    			f[i]=min(f[i],f[j-1]+dis[m]*(i-j+1)+k);
    		}
    	}
    	printf("%d
    ",f[n]-k);
    }
    
  • 相关阅读:
    FileReader读数据
    FileWriter写数据
    装饰者设计模式
    数据库连接池
    事务
    EL表达式
    console.log是异步的吗?
    使用i3wm时出现的若干问题的解决办法
    使用xmodmap修改键盘映射
    CentOS7 Minimal 安装后出现的若干问题解决办法
  • 原文地址:https://www.cnblogs.com/lcxer/p/10584322.html
Copyright © 2020-2023  润新知