[kuangbin带你飞]专题四【最短路练习】(更新中)

建议做题顺序:

dijk: 1 (7 ) 4 10 3 2 16

spfa:14 12 13 5 15 18

floyd: 6 7 9

差分约束:19 11

最后剩下一个第17题,涉及网络流,留在网络流专题做。
做题顺序来自传送门

Til the Cows Come Home (poj2387)

在这里插入图片描述
在这里插入图片描述

Sample Input

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

Sample Output

90

板子题不多赘述。

  1. 本题用到了邻接表存(可以存的下)(链式前向星存图,+ dij
    这样不用考虑重边
  2. 本题的输入是先边,后节点数

对于不懂链式前向星的,我推荐一篇blog(链式前向星是邻接表的一种)

传送门

AC

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define fzhead EDGE(int _to, int _v, int _next)
#define fzbody to(_to), v(_v), next(_next)
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define FOR(i,x,y) for (register int i=(x);i<=(y);i++)
#define mp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int>pa;
typedef pair<ll,ll>PA;
inline int read()
{
    int ans=0;
    char c=getchar();bool neg=false;
    while(c<'0'||c>'9')
    {
        if(c=='-')neg=true;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        ans=ans*10+c-'0';
        c=getchar();
    }
    return (neg)?-ans:ans;
}
void write(int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int maxn=1e3+10;
int head[maxn<<1], dis[maxn], vis[maxn];
int cnt,n,m;
struct EDGE
{
    int to,next,v;
    EDGE(){}
    fzhead:fzbody{}
}e[maxn<<1];
void add(int bg, int ed, int v)
{
    e[++cnt]=EDGE(ed, v, head[bg]);
    head[bg]=cnt;
}
inline void dij(int s)
{
    For(i, 1, n)vis[i]=0;
    priority_queue<pa>q;
    dis[s]=0;q.push(mp(0,s));
    while(!q.empty())
    {
        int u=q.top().se;
        q.pop();
        if(vis[u])continue;
        vis[u]=1;
        for(int i=head[u]; i!=-1; i=e[i].next)
        {
            if(dis[e[i].to]>dis[u]+e[i].v)
            {
                dis[e[i].to]=dis[u]+e[i].v;
                q.push(mp(-dis[e[i].to],e[i].to));
            }
        }
    }
}
int main()
{
    m=read(),n=read();
    memset(dis,0x3f,sizeof(dis));
    memset(head, -1, sizeof(head));
    For(i,1,m)
    {
        int x=read(),y=read(),v=read();
        add(x,y,v);
        add(y,x,v);
    }
    dij(n);
    write(dis[1]);
    return 0;
}

MPI Maelstrom (poj1502)

(floyd板子题,加一个stl读数据)
在这里插入图片描述
在这里插入图片描述

Sample Input

5
50
30 5
100 20 50
10 x x 10

Sample Output

35

预备知识

atoi和stoi的区别
①atoi()的参数是 const char* ,因此对于一个字符串str我们必须调用 c_str()的方法把这个string转换成 const char类型的,而stoi()的参数是const string,不需要转化为 const char*;
②stoi()会做范围检查,默认范围是在int的范围内的,如果超出范围的话则会runtime error!而atoi()不会做范围检查,如果超出范围的话,超出上界,则输出上界,超出下界,则输出下界
————————————————
版权声明:本文为CSDN博主「liuwxye」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30366449/article/details/97921986

  1. atoi(s) 是STL的一个函数,可以把一个字符数组s转化成整型数字。
  2. atoi对应char,stoi 对应string
  3. 数据小,直接floyd

哎,读题读半天英语还是不过关。。

AC(floyd)

#include <iostream>
#include <algorithm>
#include  <cstdio>
#include <cstring>
using namespace std;
const int INF=0x3f3f3f3f;
char s[110];
int cost[110][110];
int n;
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
            cost[i][j]=(i==j)?0:INF;//init
    }
    for(int i=2; i<=n; i++)
    {
        for(int j=1; j<i; j++)
        {
            scanf("%s",s);
            if(s[0]!='x')cost[i][j]=cost[j][i]=atoi(s);
        }
    }
    for(int k=1; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);
            }
        }
    }
    int ans=0;
    for(int i=1; i<=n; i++)
        if(cost[n][i]!=INF)ans=max(cost[n][i],ans);
    cout<<ans<<endl;
    return 0;
}
发布了10 篇原创文章 · 获赞 8 · 访问量 132

猜你喜欢

转载自blog.csdn.net/qq_45377553/article/details/105497375