最短路练习1

刷一会儿就睡觉好吧

POJ2387

刷水题,开心一下,注意重复边(额就是,3->5 这段路长10 但后来可能会有3->5 长5 )

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#include<iostream>
const int inf=0x3f3f3f3f;
const int N=1005;
using namespace std;
int n,m;
int tu[N][N];
int dis[N];
int vis[N];

int dijkstra(int s)
{
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    for(int i=0;i<n;i++)dis[i]=tu[i][s];
    int v;
    int mi;
    while(true){
    mi=inf;
        v=-1;
        for(int i=0;i<n;i++){
                if(!vis[i]&&mi>dis[i])
                {
                    v=i;
                    mi=dis[i];
                }
        }
        if(v==-1)
            break;
            vis[v]=1;
        for(int i=0;i<n;i++)
        {
            if(!vis[i]&&dis[i]>tu[i][v]+dis[v])
            {
                dis[i]=dis[v]+tu[i][v];
            }
        }
    }
    return dis[n-1];

}

int main()
{   int a,b,c;
    while(cin>>m>>n)
    {
        memset(dis,inf,sizeof(dis));
        memset(tu,inf,sizeof(tu));
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                tu[i][j]=inf;
        for(int i=0;i<m;i++)
        {
            cin>>a>>b>>c;
            a--;
            b--;
            if(c<tu[a][b])
            tu[a][b]=tu[b][a]=c;
        }
        cout<<dijkstra(0)<<endl;
    }

    return 0;
}



POJ2253

变向dij
挺好的一个题吧,dis里面在板子里存的是更新的到达每个点最短距离
现在可以变成到达每个点的最小边是谁
也就是说dij 的dis数组可以存来表示满足条件的值,修改松弛函数
挺好挺好,不过还是水题

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#include<iostream>
#include<iomanip>
const int inf=0x3f3f3f3f;
const int N=1005;
using namespace std;
int n,m;
double tu[N][N];
double dis[N];
int vis[N];

double dijkstra(int s)
{
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    for(int i=0;i<n;i++)dis[i]=tu[i][s];
    int v;
    int mi;
    while(true){
    mi=inf;
        v=-1;
        for(int i=0;i<n;i++){
                if(!vis[i]&&mi>dis[i])
                {
                    v=i;
                    mi=dis[i];
                }
        }
        if(v==-1)
            break;
            vis[v]=1;
        for(int i=0;i<n;i++)
        {
            dis[i]=min(dis[i],max(dis[v],tu[v][i]));
        }
    }
    return dis[1];

}
double di(int a,int b,int x,int y)
{
    return sqrt((a-x)*(a-x)*1.0+(b-y)*(b-y)*1.0);
}
int xx[N];
int yy[N];
int main()
{   int a,b,c;
int cnt=1;
    while(cin>>n&&n)
    {
        memset(dis,inf,sizeof(dis));
        memset(tu,inf,sizeof(tu));


        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                tu[i][j]=inf;


        for(int i=0;i<n;i++)
        {
            cin>>xx[i]>>yy[i];
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                tu[i][j]=di(xx[i],yy[i],xx[j],yy[j]);
            }
        }
      printf("Scenario #%d\nFrog Distance = %.3lf\n\n",cnt++,dijkstra(0));
    }

    return 0;
}



POJ1797

被一个;给卡死了
我快哭了,和上一道题差不多
为啥不用生成树做?起步更简单,大概是因为我在练最短路吧。
就是每个桥都有一定载重,问你从1到N 你载重最多是多少,感觉求个最大生成树不就完事了。

睡觉

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#include<iostream>
#include<iomanip>
const int inf=0x3f3f3f3f;
const int N=1005;
using namespace std;
int n,m;
int tu[N][N];
int dis[N];
int vis[N];
int dijkstra(int s)
{
        int v;
        for(int i=0;i<n;i++)dis[i]=tu[i][s];
        vis[s]=1;
        dis[s]=0;
        while(true)
        {
            int ma=-inf;
            v=-1;
            for(int i=0;i<n;i++)
            {
                if(!vis[i]&&dis[i]>ma)
                {
                    ma=dis[i];
                    v=i;
                }
            }

            if(v==-1)break;
            vis[v]=1;
            for(int i=0;i<n;i++)
            {
                if(vis[i]==0&&tu[i][v]!=-inf&&(dis[i]<min(tu[i][v],dis[v])))
                {
                    dis[i]=min(tu[i][v],dis[v]);

                }
            }

        }
        return dis[n-1];
}

int main()
{
    int cas;
    cin>>cas;
    int a,b,c;
    for(int o=1;o<=cas;o++)
    {
        cin>>n>>m;
       for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        tu[i][j]=-inf;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++)
        {
            cin>>a>>b>>c;
            a--;b--;
            tu[a][b]=tu[b][a]=c;
        }

        cout<<"Scenario #"<<o<<":"<<endl;
        cout<<dijkstra(0)<<endl;
        cout<<endl;
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值