zoukankan      html  css  js  c++  java
  • 【洛谷 2176】路障

    题目描述

    每天早晨,FJ从家中穿过农场走到牛棚。农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 号田,牛棚在 N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当FJ从一块田走到另一块时,总是以总路长最短的道路顺序来走。

    FJ 的牛呢,总是不安好心,决定干扰他每天早晨的计划。它们在 M 条路的某一条上安放一叠稻草堆,使这条路的长度加倍。牛希望选择一条路干扰使得FJ 从家到牛棚的路长增加最多。它们请你设计并告诉它们最大增量是多少。

    输入格式

    第 1 行:两个整数 N, M。

    第 2 到 M+1 行:第 i+1 行包含三个整数 A_i, B_i, L_i,A_i 和 B_i 表示道路 i 连接的田的编号,L_i 表示路长。

    输出格式

    第 1 行:一个整数,表示通过使某条路加倍而得到的最大增量。

    输入输出样例

    输入 #1
    5 7
    2 1 5
    1 3 1
    3 2 8
    3 5 7
    3 4 3
    2 4 7
    4 5 2
    输出 #1
    2

    说明/提示

    【样例说明】

    若使 3 和 4 之间的道路长加倍,最短路将由 1-3-4-5 变为 1-3-5。

    【数据规模和约定】

    对于 30%的数据,N <= 70,M <= 1,500。

    对于 100%的数据,1 <= N <= 100,1 <= M <= 5,000,1 <= L_i <= 1,000,000。

    题解:最后一个点TLE,吸个organ就可以过了,开心。

              普普通通的一个SPFA加上小模拟就可以了哦

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=10001;
    int x,n,m,u,v,zz,cnt,ans;
    int dis[N],head[N],vis[N];
    struct node{
        int val;
        int next;
        int to;
    }e[N];
    
    void add(int x,int y,int z){
        e[++cnt].to=y;
        e[cnt].val=z;
        e[cnt].next=head[x];
        head[x]=cnt;
    }
    queue<int>q;
    int spfa(){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        vis[1]=1; dis[1]=0; q.push(1);
        while(!q.empty()){
            x=q.front();
            q.pop(); vis[x]=0;
            for(int i=head[x];i!=0;i=e[i].next){
                v=e[i].to;
                if(e[i].val+dis[x]<dis[v]){
                    dis[v]=e[i].val+dis[x];
                    if(vis[v]==0) { vis[v]=1; q.push(v); }
                } 
            } 
        }
        return dis[n];
    }
    
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d %d %d",&u,&v,&zz);
            add(u,v,zz); add(v,u,zz);
        }
        int qwq=spfa();
        for(int i=1;i<=m;i++){
            e[i*2].val*=2;
            e[i*2-1].val*=2;
            int jjj=spfa();
            ans=max(jjj,ans);
            //cout<<ans<<endl;
            e[i*2].val/=2;
            e[i*2-1].val/=2;
        }
        printf("%d
    ",ans-qwq);
        return 0;
    }

    哈(偷偷附上一个优化版本,但是写错了90分……应该没人看见吧)

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=10001;
    int x,n,m,u,v,zz,cnt,ans;
    int dis[N],head[N],vis[N];
    
    struct node{
        int val;
        int next;
        int to;
    }e[N];
    
    void add(int x,int y,int z){
        e[++cnt].to=y;
        e[cnt].val=z;
        e[cnt].next=head[x];
        head[x]=cnt;
    }
    
    queue<int>q;
    int pre[N],fr[N],po,ioi[N],nu;
    
    int spfa(){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        vis[1]=1; dis[1]=0; q.push(1);
        while(!q.empty()){
            x=q.front();
            q.pop(); vis[x]=0;
            for(int i=head[x];i;i=e[i].next){
                v=e[i].to;
                if(e[i].val+dis[x]<dis[v]){
                    dis[v]=e[i].val+dis[x];
                    pre[v]=i; fr[v]=x;//***
                    if(!vis[v]) { vis[v]=1; q.push(v); }
                } 
            } 
        }
        return dis[n];
    }
    
    int main(){
        freopen("2176.in","r",stdin);
        freopen("2176.out","w",stdout);
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d %d %d",&u,&v,&zz);
            add(u,v,zz); add(v,u,zz);
        }
        
        int qwq=spfa();
        int now=n;
        while(now!=1){
            ioi[++nu]=pre[now];//记路径
            now=fr[now];
        }
        
        for(int i=1;i<=nu;i++){
            e[ioi[i]].val*=2;
            e[ioi[i]^1].val*=2;
            int jjj=spfa();
            ans=max(jjj,ans);
            //cout<<ans<<endl;
            e[ioi[i]].val/=2;
            e[ioi[i]^1].val/=2;
        }
        printf("%d
    ",ans-qwq);
        return 0;
    }
  • 相关阅读:
    个人永久性免费-Excel催化剂功能第18波-在Excel上也能玩上词云图
    个人永久性免费-Excel催化剂功能第17波-批量文件改名、下载、文件夹创建等
    个人永久性免费-Excel催化剂功能第16波-N多使用场景的多维表转一维表
    Excel催化剂开源第6波-Clickonce部署之自动升级瘦身之术
    Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决
    js中获取 table节点各tr及td的内容方法
    sql语句 怎么从一张表中查询数据插入到另一张表中?
    JS 如何获取自定义属性
    Ext.tree.TreePanel 属性详解
    Canvas 画圆
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11680339.html
Copyright © 2011-2022 走看看