zoukankan      html  css  js  c++  java
  • P1073 最优贸易 分层图+最长路

    洛谷p1073 最优贸易

    链接

    首先易得暴n2的暴力,暴力枚举就行
    显然1e5的数据是会炸的
    我们再分析题意,发现一共分为两个个步骤,也可以说是状态,即在一个点买入,在另一个点卖出,我们可以构建一个三层分层图
    第一层的每个点和第二层的对应点各连接一条权值为-val[i](val[i]表示i号点的水晶价格)的单向边
    表示在i号点买进,
    再在第二层的每个点向第三层的对应点各连接一条权值为val[j]的有向边
    表示在j号点卖出,
    构建好分层图后
    我们在分层图上跑最长路
    以第三层中的n号点为终点
    便可求解
    即使有负权,可我们因为跑的是最长路
    所以dijistla不受影响
    ac代码如下
    时间复杂度边为3mlog3m

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<queue>
    #define inf -0x3f3f3f3f
    using namespace std;
    const int maxn=5e5;
    inline int read(){
    	int ret=0;
    	int f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')
    			f=-f;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		ret=ret*10+(ch^'0');
    		ch=getchar();
    	}
    	return f*ret;
    }
    struct edge{
    	int nex;
    	int to;
    	int v;
    }e[maxn*3];
    struct node{
    	int u,d;
    	bool operator <(const node &x) const{
    		return x.d>d;
    	}
    };
    
    int head[maxn*3];
    int cnt;
    void add(int u,int to,int v){
    	cnt++;
    	e[cnt].nex=head[u];
    	e[cnt].to=to;
    	e[cnt].v=v;
    	head[u]=cnt;
    }
    int n,m;
    int dis[maxn*3];
    int val[maxn];
    inline void di(int s){
    	for(int i=1;i<=n;i++){
    		dis[i]=inf;
    	}
    	dis[s]=0;
    	priority_queue<node>q;
    	q.push((node){s,0});
    	while(!q.empty()){
    		node f=q.top();
    		q.pop();
    		int u=f.u;
    		int d=f.d;
    		if(dis[u]!=d)
    			continue;
    		for(int i=head[u];i;i=e[i].nex){
    			int v=e[i].v;
    			int y=e[i].to;
    			if(dis[u]+v>dis[y]){
    				dis[y]=dis[u]+v;
    				q.push((node){y,dis[y]});
    			}
    		}
    			
    	}
    }
    int main(){
    //	freopen("a.in","r",stdin);
    	n=read();
    	m=read();
    	for(int i=1;i<=n;i++){
    		val[i]=read();
    		add(i,i+n,-val[i]);
    		add(i+n,+2*n+i,val[i]);
    	}
    	int x,y,z;
    	for(int i=1;i<=m;i++){
    		x=read();
    		y=read();
    		z=read();
    		add(x,y,0);
    		add(x+n,y+n,0);
    		add(x+2*n,y+2*n,0);
    		if(z==2){
    			add(y,x,0);
    			add(y+n,x+n,0);
    			add(y+2*n,x+2*n,0);
    		}
    	}
    	n=n*3;
    	di(1);
    	cout<<dis[n];
    	return 0;
    }
    

    结束喽!

  • 相关阅读:
    Cocos2d-JS中的Sprite精灵类
    Cocos2d-JS中的精灵菜单和图片菜单
    Cocos2d-JS中的文本菜单
    SpringMVC01
    xml文件
    MyEclipse保存文件时 自动格式化代码! 不包括文档注释
    MyEclipse修改servlet模版
    java05 选择结构
    ssh注解开发
    使用socket实现聊天功能
  • 原文地址:https://www.cnblogs.com/rpup/p/13616317.html
Copyright © 2011-2022 走看看