kuangbin专题四 最短路练习【从入门到熟练】

【POJ 2253 Frogger】

这道题求从u到v中所有通路的最大边最小

我直接二分做了,但实际上这种题是最短路算法的变种,意义在于告诉我们spfa这些算法不仅能维护出最短路,稍加修改后可以维护出很多其他东西。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<string>
#include<stack>
#include<fstream>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
#define INF 2e9
#define maxnode 200000
#define ll long long
#define lowbit(x) (x&(-x))
const int mod = 10007;
const int MAXN = 2e2 + 10;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
using namespace std;

struct node{
    int v,d;
    node(int v1,int d1): v(v1),d(d1) {}
};

vector<node> edges[MAXN];

int dist[MAXN],visit[MAXN],n;
void spfa(){
    for(int i=1;i<=n;i++) dist[i]=INF;
    dist[1]=0; visit[1]=1;
    queue<int> q;
    q.push(1);
    while( !q.empty() ){
        int u = q.front(); q.pop();
        visit[u]=0;
        for(int i=0;i<edges[u].size();i++){
            int v = edges[u][i].v;
            if( dist[v]>dist[u]+edges[u][i].d ){
                dist[v] = dist[u]+edges[u][i].d;
                if( !visit[v] ) q.push(v);
            }
        }
    }

}

int x[MAXN],y[MAXN];
double dis[MAXN][MAXN];

int main(){
    //ios::sync_with_stdio(false);
    int tc=0;
    while(1){
        scanf("%d",&n);
        if(n==0) break;
        for(int i=1;i<=n;i++) scanf("%d%d",x+i,y+i);

        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                double x1 = abs(x[i]-x[j]);
                double y1 = abs(y[i]-y[j]);
                dis[i][j] = sqrt(x1*x1 + y1*y1);
                //cout<<i<<" "<<j<<" "<<dis[i][j]<<endl;
            }
        }

        double start=0,end=3000,mid;
        while( end-start>=0.00001 ){
            mid = (start+end)/2;
            for(int i=1;i<=n;i++) edges[i].clear();

            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if( mid>=dis[i][j] ) edges[i].push_back( node(j,1) );
                }
            }

            spfa();
            if( dist[2]!=INF ) end=mid;
            else start=mid;
        }
        printf("Scenario #%d\n",++tc);
        printf("Frog Distance = %.3lf\n",end);
        printf("\n");
    }    

    return 0;
}

【POJ 1797 Heavy Transportation】

维护所有通路的最小边最大

那修改后的松弛操作就是 dist[v] = max( dist[v], min( dist[u], edges[u][i].d ) )

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<string>
#include<stack>
#include<fstream>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
#define INF 2e9
#define maxnode 200000
#define ll long long
#define lowbit(x) (x&(-x))
const int mod = 10007;
const int MAXN = 1e3 + 10;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
using namespace std;

struct node{
    int v,d;
    node(int v1,int d1): v(v1),d(d1) {}
};

vector<node> edges[MAXN];

int dist[MAXN],visit[MAXN],n,m;//dist[i]代表从源点到i点中所有通路的最小边最大值
void spfa(){
    for(int i=1;i<=n;i++) dist[i]=0;
    dist[1]=INF; visit[1]=1;
    queue<int> q;
    q.push(1);
    while( !q.empty() ){
        int u = q.front(); q.pop();
        visit[u]=0;
        for(int i=0;i<edges[u].size();i++){
            int v = edges[u][i].v;
            int weight = min( edges[u][i].d,dist[u] );//weight是这条通路上的最小边
            if( weight>dist[v] ){
                dist[v] = weight;
                if( !visit[v] ) {
                    //visit[v]=1;
                    q.push(v);
                }
            }
        }
    }

}

//找所有通路中最小边最大的
int main(){
    //ios::sync_with_stdio(false);
    int t,tc=0; scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v,d; scanf("%d%d%d",&u,&v,&d);
            edges[u].push_back( node(v,d) );
            edges[v].push_back( node(u,d) );
        }

        spfa();
        printf("Scenario #%d:\n",++tc);
        printf("%d\n",dist[n]);
        printf("\n");

        for(int i=1;i<=n;i++) edges[i].clear();
    }    

    return 0;
}

【POJ 3268 Silver Cow Party】

想到跑flyod但n^3太慢就t了,实际上反向建边跑两边spfa就可以了!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<string>
#include<stack>
#include<fstream>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
#define INF 2e9
#define maxnode 200000
#define ll long long
#define lowbit(x) (x&(-x))
const int mod = 10007;
const int MAXN = 1e3 + 10;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
using namespace std;

struct node{
    int v,d;
    node(int v1,int d1): v(v1),d(d1) {}
};
vector<node> edges[MAXN];
int vis[MAXN],dist1[MAXN],dist2[MAXN],n,m,x;

void spfa1(){
    for(int i=1;i<=n;i++) dist1[i]=INF;
    queue<int> q;
    q.push(x); vis[x]=1; dist1[x]=0;
    while(!q.empty()){
        int u = q.front(); q.pop();
        vis[u]=0;
        for(int i=0;i<edges[u].size();i++){
            int v = edges[u][i].v;
            int d = edges[u][i].d;
            if( dist1[u]+d<dist1[v] ){
                dist1[v]=dist1[u]+d;
                if( !vis[v] ){
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}

void spfa2(){
    for(int i=1;i<=n;i++) dist2[i]=INF;
    queue<int> q;
    q.push(x); vis[x]=1; dist2[x]=0;
    while(!q.empty()){
        int u = q.front(); q.pop();
        vis[u]=0;
        for(int i=0;i<edges[u].size();i++){
            int v = edges[u][i].v;
            int d = edges[u][i].d;
            if( dist2[u]+d<dist2[v] ){
                dist2[v]=dist2[u]+d;
                if( !vis[v] ){
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }

}

int u[100005],v[100005],d[100005];

int main(){
    //ios::sync_with_stdio(false);
    while( scanf("%d%d%d",&n,&m,&x)!=EOF ){

        for(int i=1;i<=m;i++){
            scanf("%d%d%d",u+i,v+i,d+i);
            edges[ u[i] ].push_back( node(v[i],d[i]) );
        }

        spfa1();
        for(int i=1;i<=n;i++) edges[i].clear();
        for(int i=1;i<=m;i++) edges[ v[i] ].push_back( node(u[i],d[i]) );
        spfa2();

        int ans=-1;
        for(int i=1;i<=n;i++){//枚举所有cows
            ans = max( ans,dist1[i]+dist2[i] );
        }
        printf("%d\n",ans);

        for(int i=1;i<=n;i++) edges[i].clear();            

    }    

    return 0;
}

【】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<string>
#include<stack>
#include<fstream>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
#define INF 2e9
#define maxnode 200000
#define ll long long
#define lowbit(x) (x&(-x))
const int mod = 10007;
const int MAXN = 1e2 + 10;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
using namespace std;

struct exchange{
    int type;
    double r,c;
    exchange(int t1,double r1,double c1): type(t1),r(r1),c(c1) {}
};

vector<exchange> edges[MAXN];//edges[i]是拿着i货币能选择的一些兑换方案 

double d[MAXN],money;
int n,m,s;

struct node{
    int type;
    double m;//状态是拿着m个type钱
    node(int t1,double m1): type(t1),m(m1) {}
};

bool bfs(){
    for(int i=1;i<=n;i++) d[i]=-INF;//最优性剪枝,d[i]为i种货币最多有多少个
    queue<node> q;
    q.push( node(s,money) ); d[s]=money;
    while( !q.empty() ){
        node p = q.front(); q.pop();
        if( p.type==s && p.m>money ) return true;
        for(int i=0;i<edges[p.type].size();i++){//能怎么换
            exchange e = edges[p.type][i];//在这个所换
            double m1 = (p.m-e.c)*e.r;
            if( m1>d[ e.type ] ){
                d[e.type]=m1;
                q.push( node(e.type,m1) );
            }
        }
    }

    return false;
}

int main(){
    //ios::sync_with_stdio(false);
    while( scanf("%d%d%d%lf",&n,&m,&s,&money)!=EOF ){

        for(int i=1;i<=m;i++){
            int a,b;
            double r1,c1,r2,c2; scanf("%d%d%lf%lf%lf%lf",&a,&b,&r1,&c1,&r2,&c2);
            edges[a].push_back( exchange(b,r1,c1) );
            edges[b].push_back( exchange(a,r2,c2) );
        }

        if( bfs() ) printf("YES\n");
        else printf("NO\n");

        for(int i=1;i<=n;i++) edges[i].clear();
    }    

    return 0;
}

原文地址:https://www.cnblogs.com/ZhenghangHu/p/9869298.html

时间: 2024-07-29 10:45:46

kuangbin专题四 最短路练习【从入门到熟练】的相关文章

kuangbin专题四 : 最短路 I 题 Arbitrage

kuangbin专题四 : 最短路 I 题  Arbitrage POJ 2240 Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 1 US Dollar buys 0.5 British pound,

【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 邻接矩阵实现的单源最短路 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include

kuangbin专题四、最短路练习

题意:给你t条路径之间的关系,问你从n点走到1的最短路是多少,Dijkstra写一遍就行 Dijkstra理解:从起点s开始找到与之相连最短的点s',标记s',再更新s到与s'相连的点s''的最短距离,再从s''中找到到s的最短的一个,标记,再更新s到与s''相连的点的最短距离,循环往复,总之:就是不断标记最短点,再从该点出发,继续寻找.直到标记所有的点,更新完所有dis[i]. 话很绕,不如看图: 1 #include<iostream> 2 #include<cstdio> 3

[ An Ac a Day ^_^ ][kuangbin带你飞]专题四 最短路练习 POJ 2240 Arbitrage spfa求负环

题意就是问倒腾外币能不能升值 不用spfa 用其他的最短路算法也可以 松弛条件换成dist[v]<dist[u]*e[u][i].value 当然 貌似只有spfa有这个坑…… 有A  (value>1.0) A 这种情况……我的天 用Dij Floyd都只用判断如果松弛到了自己 那么一定有环 直接跳出就行 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<

[kuangbin带你飞]专题四 最短路练习

A. POJ 2387  Til the Cows Come Home 模板题. #include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<vector> #include<string> #include<map> #include<queue> #in

[ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home

求1到N的最短路 注意有重边 跑一遍dijkstra就行 1 /* *********************************************** 2 Author :SunYuefeng 3 Created Time :2016/10/22 14:18:06 4 File Name :A.cpp 5 ************************************************ */ 6 7 #include<cstdio> 8 #include<io

[kuangbin带你飞]专题四 最短路练习 POJ 2253 Frogger

求第一个点到第二个点的所有通路上最长的边 dijkstra的变形 每次松弛的是每条边通路上的的最长的边 WA了好几次是因为用了%lf 改成%f就过了…… 1 /* *********************************************** 2 Author :SunYuefeng 3 Created Time :2016/10/22 14:18:06 4 File Name :A.cpp 5 ******************************************

[kuangbin带你飞]专题四 最短路练习 E - Currency Exchange

E - Currency Exchang 题目链接:https://vjudge.net/contest/66569#problem/E 题目: Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with thes

[kuangbin带你飞]专题四 最短路练习 F - Wormholes (判断负环)

F - Wormholes 题目链接:https://vjudge.net/contest/66569#problem/F 题目: While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination