zoukankan      html  css  js  c++  java
  • 【提高组】最短路

    P1339 [USACO09OCT]热浪Heat Wave

    板子题,练习堆优dj。

    #include<bits/stdc++.h>
    #define For(i,l,r) for(int i=l;i<=r;i++)
    using namespace std;
    const int M=6206*2;
    int n,m,s,f,head[M],tot,dis[M];
    bool vis[M];
    typedef pair<int,int> PII;
    priority_queue<PII,vector<PII>,greater<PII> > Q;
    struct node{
        int nxt,to,v;
    }e[M];
    inline void add(int u,int v,int w){
        e[++tot].to=v;
        e[tot].nxt=head[u];
        e[tot].v=w;
        head[u]=tot;
    } 
    int main(){
        scanf("%d%d%d%d",&n,&m,&s,&f);
        For(i,1,m){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);add(y,x,z);
        }
        memset(dis,0x3f3f3f,sizeof(dis));
        dis[s]=0;Q.push(make_pair(0,s));
        while(!Q.empty()){
            int x=Q.top().second;Q.pop();
            if(vis[x]) continue;
            vis[x]=1;
            for(int i=head[x];i;i=e[i].nxt){
                int to=e[i].to;
                if(dis[to]>dis[x]+e[i].v){
                    dis[to]=dis[x]+e[i].v;
                    Q.push(make_pair(dis[to],to));
                }
            }
        }
        printf("%d",dis[f]);
        return 0;
    }
    View Code

    P1462 通往奥格瑞玛的道路

    二分+dj。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=10010;
    struct pp
    {
        int u;
        int v;
        int w;
        int nex;
    }e[maxn*maxn];
    struct node
    {
        int dis;
        int pos;
        bool operator <(const node &x) const
        {
            return x.dis<dis;
        }
    };
    int dis[maxn],head[maxn],vis[maxn],cost[maxn],f[maxn];
    int n,m,b,s,ans,cnt,res,flag,maxl,l,r;
    priority_queue <node> q;
    void add(int x,int y,int z)
    {
        e[++cnt].u=x;
        e[cnt].v=y;
        e[cnt].w=z;
        e[cnt].nex=head[x];
        head[x]=cnt;
    }
    bool go( int t)
    {
    
        for(int i=1;i<=n;i++) dis[i]=1000000010,vis[i]=0;
        dis[1]=0;
        q.push((node) {0,1});
    
        //for(int i=1;i<=n;i++)
        //if(cost[i]>t) vis[i]=1;
        //else vis[i]=0;
        while(!q.empty())
        {
            node tmp=q.top();
            q.pop();
            int x=tmp.pos;
            if(vis[x]) continue;
            vis[x]=1;
            for(int i=head[x];i;i=e[i].nex)
            {
                int y=e[i].v;
                if(dis[y]>dis[x]+e[i].w&&cost[y]<=t)
                {
                    dis[y]=dis[x]+e[i].w;
                    if(!vis[y])
                    q.push((node) {dis[y],y} );
    
                }
            }
        }
        if(dis[n]<b) return true;
        else return false;
    
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&b);
        for(int i=1;i<=n;i++)
        scanf("%d",&f[i]),cost[i]=f[i];
        sort(f+1,f+1+n);
        for(int i=1;i<=m;i++)
        {
            int aa,bb,cc;
            scanf("%d%d%d",&aa,&bb,&cc);
            add(aa,bb,cc);add(bb,aa,cc);
        }
        l=1;r=n;
        if(!go(f[n]+8)) 
        {
            printf("AFK");
            return 0;
        }
        while (l<=r)
        {
            int mid=(l+r)>>1;
            if(go(f[mid])) ans=f[mid],r=mid-1;
            else l=mid+1;
    
        }
        printf("%d",ans);
        return 0;
    }
    View Code

    P1119 灾后重建

    很好地考察算法(Floyd)理解的题目。一轮复习时一定要理解算法+充分刷题。同时也提醒了我要重视数据范围

    以为比较难,直接往堆优dj想,没认真考虑数据范围,想当然地以为除了堆优dj一定会炸时间(结果堆优炸了),很快想出了一个写法。

    结果:改了半天发现没read( )没初始化dis没判断dis1>dis2+w(多打题,做题时保持精神)->过了样例提交20分,结构体开小了,node记得<<1(还顺手打成了>>)但写成了点而非边->再交T了40分打了个输出优化->50分T了->开了O2T了70分->意识到算法有问题但又懒得想&改了翻题解,哇原来是Floyd。

    代码简单又好想。主要难在对Floyd算法的理解与意识到可以用Floyd过。

    #include<bits/stdc++.h>
    using namespace std;
    const int M=205;
    int n,m,a[M],f[M][M];
    inline void updata(int k){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(f[i][j]>f[i][k]+f[j][k])
                    f[i][j]=f[j][i]=f[i][k]+f[k][j];
            }
        }
        return;
    }
    int main(){
        cin>>n>>m;
        for(int i=0;i<n;i++) scanf("%d",a+i);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                f[i][j]=0x3f3f3f3f;
            }
            f[i][i]=0;
        }
        int s1,s2,s3;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&s1,&s2,&s3);
            f[s1][s2]=f[s2][s1]=s3;
        }
        int q,now=0;
        cin>>q;
        for(int i=1;i<=q;i++){
            scanf("%d%d%d",&s1,&s2,&s3);
            while(a[now]<=s3&&now<n){
                updata(now);now++;
            }
            if(a[s1]>s3||a[s2]>s3) cout<<-1<<endl;
            else{
                if(f[s1][s2]==0x3f3f3f3f) cout<<-1<<endl;
                else cout<<f[s1][s2]<<endl;
            }
        }
        return 0;
    } 
    View Code

    附上Floyd理解好文   https://www.cnblogs.com/GumpYan/p/5540549.html

     

    P1522 牛的旅行 Cow Tours

    1.计算每个牧场的直径:枚举计算牧场中每个点距离其他点的距离,不连通则初始化为inf(读懂输入中给的矩阵..花了我一会儿)。然后Floyd跑最短路。

    2.计算新牧场直径:枚举不联通的点,直径为两个点分别离其他点的最大距离+两个点的距离中的最小值。

    3.计算结果:ans=max(每个牧场的直径,新牧场直径)。

    难点在读懂题目吧...好绕。

    #include<bits/stdc++.h>
    #define For(i,l,r) for(int i=l;i<=r;i++)
    using namespace std;
    const int M=155,inf=0x3f3f3f3f;
    int n,tmp;
    double dis[M][M],l[M],l1,l2=inf,ans;
    struct node{
        int x,y;
    }a[M];
    double cal(int i,int j){return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));}
    int main(){
        scanf("%d",&n);
        For(i,1,n) scanf("%d%d",&a[i].x,&a[i].y);
        For(i,1,n)
          For(j,1,n){
              scanf("%1d",&tmp);
            if(tmp) dis[i][j]=cal(i,j);
            else if(i!=j)dis[i][j]=inf;
          }  
        For(k,1,n)
          For(i,1,n)
            For(j,1,n)
              if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j];
        For(i,1,n)
          For(j,1,n){
              if(dis[i][j]!=inf) l[i]=max(l[i],dis[i][j]);
            l1=max(l1,l[i]);
          } 
        For(i,1,n){
            For(j,1,n){
                if(dis[i][j]==inf){
                    l2=min(l[i]+l[j]+cal(i,j),l2);
                }
            }
        }
        ans=max(l1,l2);
        printf("%.6f",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    201521123108 《Java程序设计》第八周学习总结
    201521123108 《Java程序设计》第7周学习总结
    201521123108 《Java程序设计》第6周学习总结
    201521123108 《Java程序设计》第5周学习总结
    201521123108 《Java程序设计》第4周学习总结
    201521123108《Java程序设计》第3周学习总结
    201521123107 《Java程序设计》第11周学习总结
    201521123107 《Java程序设计》第10周学习总结
    201521123107 《Java程序设计》第9周学习总结
    201521123107 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/jian-song/p/11644605.html
Copyright © 2011-2022 走看看