• P3008 [USACO11JAN]Roads and Planes G (最短路)


    不要问我为啥不加天数了,问就是数不过来了

    题目大意

    Farmer John 正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到 T个城镇 ,编号为 1到T 。这些城镇之间通过R 条道路(编号为1 到 R)和 条航线(编号为 1到 P)连接。每条道路 i或者航线i 连接城镇Ai 到 Bi,花费为Ci 。

    对于道路0<=Ci<=104,然而航线的花费很神奇,花费Ci可能是负数。道路是双向的,可以从Ai到Bi,也可以从Bi到Ai,话费都是Ci,然而航线与之不同,只可以Ai到Bi。

    事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从Ai到Bi,那么保证不可能通过一些道路和航线从Bi回到Ai。由于 FJ 的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇S把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。

    输入格式

    第一行为四个空格隔开的整数:T,R,P,S;

    第二到第R+1行:三个空格隔开的整数(表示一条道路):Ai,Bi和Ci;

    第R+2到R+P+1行:三个空格隔开的整数(表示一条航线):Ai,Bi和Ci。

    输出格式

    输出T行,第i行表示到达城镇i的最小花费,如果不存在输出NO PATH。

    样例

    样例输入

    6 3 3 4 
    1 2 5 
    3 4 5 
    5 6 10 
    3 5 -100 
    4 6 -100 
    1 3 -10 
    

    样例输出

    NO PATH 
    NO PATH 
    5 
    0 
    -95 
    -100 
    

    数据范围与提示

    对于全部数据,1<=T<=2.5×104,1<=R,P<=5×104,1<=Ai,Bi,S<=T,保证对于所有的道路,0<=Ci<=104,对于所有的航线,-104<=Ci<=104.

    算法分析:

    • 这题再看不出来是SPFA就该吃**了
    • 但是挂了
    • 这个题用SPFA会T掉 (加上队列优化一样会T掉) , 所以我们需要别的优化:STL
    • STL主要利用双端队列优化

    代码展示

    //不加STL优化会T到88分 加STL会不会T主要看脸………… 建议交之前洗把脸 (如果一次T了就多交两次) 
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    int head[maxn],cnt;
    int dis[maxn],vis[maxn];
    
    struct node{
    	int next,to,dis;
    }a[maxn];
    
    void add(register int x,int y,int z){
    	a[++cnt].to = y;
    	a[cnt].dis = z;
    	a[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    int read(){
        char ch=getchar();int ans=0,p=1;
        while(ch>'9'||ch<'0'){
            if(ch=='-') p=-1;
            ch=getchar();
        }
        while(ch<='9'&&ch>='0'){
            ans=(ans<<1)+(ans<<3)+ch-'0';
            ch=getchar();
        }
        return ans*p;
    }
    
    void spfa(register int x){
        memset(dis,0x3f,sizeof(dis));
        deque<int> q;q.push_back(x),dis[x]=0;//双端队列
        while(!q.empty())
        {
            int now=q.front();q.pop_front();
            vis[now]=0;
            for(register int i=head[now];i;i=a[i].next)
            {
                int v=a[i].to;
                if(dis[v]>dis[now]+a[i].dis)
                {
                    dis[v]=dis[now]+a[i].dis;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);//双端队列优化 将距离最小的放在队首(优化效果有点玄学 但是平均优化在15% ~ 20%之间)
                        else q.push_back(v);
                    }
                }
            }
        }
    }
    
    int main(){
    	int n = read(),r = read(),p = read(),s = read();
    	for(register int i = 1;i <= r;++i){
    		int x = read(),y = read(),w = read();
    		add(x,y,w);
    		add(y,x,w);
    	}
    	for(register int i = 1;i <= p;++i){
    		int x = read(),y = read(),w = read();;
    		add(x,y,w);
    	}
    	spfa(s);
    	for(register int i = 1;i <= n;++i){
    		if(dis[i] == 0x3f3f3f3f){printf("NO PATH
    ");continue;}
    		printf("%d
    ",dis[i]);
    	}
    	return 0;
    }
    
    

    附: 竞赛SPFA常用STL优化 不仅好写而且优化效果比较明显 还有第二种优化是LLL 但是竞赛中不常用(不好写) 可以自行百度扩展 (STL + LLL俩一起用大概优化在50%左右)

  • 相关阅读:
    URL重写,asp.net URL重写,URLRewriter.dll下载,URLRewriter,URLRewriter下载,URL重写学习
    C#制作图像旋转的程序范例

    去掉qq空间不能添加带“=”号的网络音乐地址限制
    《Javascript高级程序设计》读书笔记(二)
    NExcelAPI使用测试
    常用的开源组件
    [转]编程的首要原则(s)是什么?
    《Javascript高级程序设计》读书笔记(一)
    [转]SQL错误处理的脆弱性演示
  • 原文地址:https://www.cnblogs.com/2004-08-20/p/13277506.html
Copyright © 2020-2023  润新知