zoukankan      html  css  js  c++  java
  • CJOJ 免费航班

    Description

    小Z在MOI比赛中获得了大奖,奖品是一张特殊的机 票。使用这张机票,可以在任意一个国家内的任意城市之间的免费飞行,只有跨国飞行时才会有额外的费用。小Z获得了一张地图,地图上有城市之间的飞机航班和 费用。已知从每个城市出发能到达所有城市,两个城市之间可能有不止一个航班。一个国家内的每两个城市之间一定有不止一条飞行路线,而两个国家的城市之间只 有一条飞行路线。小Z想知道,从每个城市出发到额外费用最大的城市,以便估算出出行的费用,请你帮助他。当然,你不能通过乘坐多次一个航班增加额外费用, 也就是必须沿费用最少的路线飞行。

    Input

    第一行,两个整数N,M,表示地图上有N个城市,M条航线。
    接下来M行,每行三个整数a,b,c,表示城市a,b之间有一条费用为c的航线。

    Output

    共N行,第i行为从城市i出发到达每个城市额外费用的最大值。

    Sample Input

    6 6
    1 4 2
    1 2 6
    2 5 3
    2 3 7
    6 3 4
    3 1 8

    Sample Output

    4
    4
    4
    6
    7
    7

    Hint

    样例说明
    有四个国家,包含的城市分别为 {1,2,3},{4},{5},{6}。从城市1出发到达城市6,乘坐(1,3)(3,6)两个航班费用最大,(1,3)在国内为免费航班,(3,6)的费用为4,所以从1出发的最大费用为4。

    数据规模
    对于30%的数据 1<=N<=1000,1<=M<=1000
    对于100%的数据 1<=N<=20000,1<=M<=200000

    Source

    动态规划 ,连通性

    根据题目描述,每个国家是一个边双连通分量,把每个边双连通分量缩点后,原图变为一棵树.

    相当于是求树上每个点在树上的最长路.

    所有点的树上最长路可以通过两边dfs进行DP;

    第一遍:求出每个点只到他子树内部的最长路和次长路

    第二遍:每个点再由他父亲来更新往改点的子树外走的最长路,因为该点到子树外面的路必经过他爸爸

    具体实现就是最长路和次长路转化,转移画画图就好了

    边双连通缩点的话就是把桥标记后在dfs一遍

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #define RG register
    using namespace std;
    typedef long long ll;
    const int N=20050;
    int gi(){
      int x=0;
      char ch=getchar();
      while(ch<'0'||ch>'9') ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
      return x;
    }
    int head[N],nxt[N*20],to[N*20],dfn[N],low[N],vis[N],zhan[N],w[N*20],cnt=1,tot,sum,top,pd[N*20];
    vector<int>q[N],p[N],W[N];
    int dis[N][2],vis2[N],fr[N];
    void tarjan(int x,int fa){
      dfn[x]=low[x]=++sum;
      for(RG int i=head[x];i;i=nxt[i]){
          int y=to[i];
          if(!dfn[y]){
    	  tarjan(y,x);
    	  low[x]=min(low[x],low[y]);
    	  if(low[y]>dfn[x]) pd[i]=pd[i^1]=1;
    	}
          else if(y!=fa) low[x]=min(low[x],dfn[y]);
        }
    }
    void dfs3(int x,int gg){
      fr[x]=gg,vis[x]=1;
      q[gg].push_back(x);
      for(RG int i=head[x];i;i=nxt[i]){
          if(!pd[i]&&!vis[to[i]]) dfs3(to[i],tot);
        }
    }
    void dfs1(int x){
        vis2[x]=1;
        for(RG int i=0;i<p[x].size();i++){
    	int y=p[x][i],w=W[x][i];
    	if(!vis2[y]){
    	    dfs1(y);
    	    if(dis[y][1]+w>=dis[x][1]){
    		dis[x][0]=dis[x][1];
    		dis[x][1]=dis[y][1]+w;
    	    }
    	    else dis[x][0]=max(dis[x][0],dis[y][1]+w);
    	}
        }
    }
    void dfs2(int x){
        vis2[x]=1;
        for(RG int i=0;i<p[x].size();i++){
    	int y=p[x][i],w=W[x][i];
    	if(!vis2[y]){
    	    if(dis[y][1]+w==dis[x][1]){
    		dis[y][0]=max(dis[y][0],min(dis[x][1]-w,dis[x][0]+w));
    		dis[y][1]=max(dis[x][1]-w,dis[x][0]+w);
    	    }
    	    else{
    		dis[y][0]=max(dis[y][0],max(dis[x][0]+w,min(dis[y][1],dis[x][1]+w)));
    		dis[y][1]=max(dis[y][1],dis[x][1]+w);
    	    }
    	    dfs2(y);
    	}
        }
    }
    int main(){
      int n,m,x,w1,y;
      cnt=1;n=gi(),m=gi();
      for(RG int i=1;i<=m;i++){
          x=gi(),y=gi(),w1=gi();
          to[++cnt]=y,w[cnt]=w1,nxt[cnt]=head[x],head[x]=cnt;
          to[++cnt]=x,w[cnt]=w1,nxt[cnt]=head[y],head[y]=cnt;
        }
      tarjan(1,1);
      for(int i=1;i<=n;i++) if(!vis[i]) dfs3(i,++tot);
      for(RG int i=1;i<=tot;i++)
        for(RG int j=0;j<q[i].size();j++)
          for(RG int k=head[q[i][j]];k;k=nxt[k]){
    	  int y=fr[to[k]],w1=w[k];
    	  if(y!=i){
    	      p[i].push_back(y);
    	      W[i].push_back(w1);
    	    }
    	}
      dfs1(1);for(RG int i=1;i<=tot;i++) vis2[i]=0;
      dfs2(1);for(RG int i=1;i<=n;i++) printf("%d
    ",dis[fr[i]][1]);
      return 0;
    }
    
  • 相关阅读:
    5 Things Every Manager Should Know about Microsoft SharePoint 关于微软SharePoint每个经理应该知道的五件事
    Microsoft SharePoint 2010, is it a true Document Management System? 微软SharePoint 2010,它是真正的文档管理系统吗?
    You think you use SharePoint but you really don't 你认为你使用了SharePoint,但是实际上不是
    Introducing Document Management in SharePoint 2010 介绍SharePoint 2010中的文档管理
    Creating Your Own Document Management System With SharePoint 使用SharePoint创建你自己的文档管理系统
    MVP模式介绍
    权重初始化的选择
    机器学习中线性模型和非线性的区别
    神经网络激励函数的作用是什么
    深度学习中,交叉熵损失函数为什么优于均方差损失函数
  • 原文地址:https://www.cnblogs.com/qt666/p/6880132.html
Copyright © 2011-2022 走看看