ACM之最短路径做题笔记与记录

在这里纪念一下从4月开始一直因为事情而荒废了的最短路,多亏了jbb的帮助,我才完成了FZU热身赛一题简单的一个用模拟链表存边以及最短路径的学习,目前(6.5)已经学会使用了最简单的djstral与spfa,以及优先队列优化的dj,这里是最近2天做出来的题目,在这里记录一下

HUD1221 HDU Today

这题需要注意的就是可能存在回路,头尾一个点

//dijkstral + 动态数组
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int INF = 10000000;
struct E
{
    int to;
    int d;
};
int main()
{
    int N;
    while (scanf("%d",&N),N!=-1)
    {
        char s1[100],s2[100];
        vector<E>head[160];
        map<string,int> mp;
        scanf("%s %s",s1,s2);
        mp[s1] = 1;
        mp[s2] = 2;
        int len = 3;
        bool flag = strcmp(s1,s2) == 0;
        for (int i = 1; i < N + 1; i++)
        {
            int d;
            scanf("%s %s %d",s1,s2,&d);
            if(!mp[s1])
            {
                mp[s1] = len++;
            }
            if(!mp[s2])
            {
                mp[s2] = len++;
            }
            
            int u = mp[s1];
            int v = mp[s2];
            
            E tmp;
            tmp.d = d;
            
            tmp.to = u;
            head[v].push_back(tmp);
            
            tmp.to = v;
            head[u].push_back(tmp);
            
        }
        if(flag)
        {
            printf("0\n");
            continue;
        }
        
        int d[160];
        bool vis[160] = {false}; 
        fill(d,d+160,INF);
        d[1] = 0;
        while(true)
        {
            
            int nod = -1;
            for(int i = 1 ; i < len; i++)
            {
                if(!vis[i] && (nod == -1 || d[nod] > d[i]))
                {
                    nod = i;
                }
            }
            
            if(nod == -1) break;
            vis[nod] = true;
            for (int i = 0; i < head[nod].size(); i++)
            {
                if(d[head[nod][i].to] > d[nod] + head[nod][i].d)
                {
                    d[head[nod][i].to] =  d[nod] + head[nod][i].d;
                }
            }
        }
        if(d[2] == INF)
        {
            printf("-1\n");
            
        }
        else
        printf("%d\n",d[2]);
    }
}
//dijkstral + 模拟链表
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue> 
#include<map>
using namespace std;
const int INF = 10000000;
struct E
{
    int to;
    int d;
    bool operator < (const E &T) const
    {
        return d < T.d;
    }
};
int main()
{
    int N;
    while (scanf("%d",&N),N!=-1)
    {
        char s1[100],s2[100];
        vector<E>head[160];
        map<string,int> mp;
        scanf("%s %s",s1,s2);
        mp[s1] = 1;
        mp[s2] = 2;
        int len = 3;
        bool flag = strcmp(s1,s2) == 0;
        for (int i = 1; i < N + 1; i++)
        {
            int d;
            scanf("%s %s %d",s1,s2,&d);
            if(!mp[s1])
            {
                mp[s1] = len++;
            }
            if(!mp[s2])
            {
                mp[s2] = len++;
            }
            
            int u = mp[s1];
            int v = mp[s2];
            
            E tmp;
            tmp.d = d;
            
            tmp.to = u;
            head[v].push_back(tmp);
            
            tmp.to = v;
            head[u].push_back(tmp);
            
        }
        
        if(flag)
        {
            printf("0\n");
            continue;
        }
        
        int d[160];
        fill(d,d+160,INF);
        d[1] = 0;
        priority_queue<E> que;
        E tmp;
        tmp.d = 0;
        tmp.to = 1;
        que.push(tmp);
        
        while (!que.empty())
        {
            tmp = que.top();
            que.pop();
            int u = tmp.to;
            if(d[u] < tmp.d) continue;
            
            for(int i = 0; i < head[u].size(); i++)
            {
                int v = head[u][i].to;
                if(d[v] > d[u] + head[u][i].d)
                {
                    d[v] = d[u] + head[u][i].d;
                    E ttt;
                    
                    ttt.d = d[v];
                    ttt.to = v;
                    
                    que.push(ttt);
                }
            }
        }
        
        
        if(d[2] == INF)
        {
            printf("-1\n");
            
        }
        else
        printf("%d\n",d[2]);
    }
}
//SPFA
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
//lower_bound(a+1,a+1+len1,x) - a - 1;
typedef long long LL;
const int INF = 10000000;
using namespace std;
struct E
{
    int cost;
    int nod;
};

int main()
{
//    freopen("xx.in","r",stdin);
//    freopen("xx.out","w",stdout);
    int N;
    while (scanf("%d",&N),N!=-1)
    {
        char a[100],b[100];
        bool flag = false;

        E edge[20010];
        map<string,int> mp;
        scanf("%s %s",a,b);
        if(strcmp(a,b) == 0) flag = true;
        mp[a] = 1;
        mp[b] = 2;
        int len = 3;
        vector<int> head[160];
        for (int i = 1; i < N + 1 ; i++)
        {
            int d;
            scanf("%s %s %d",a,b,&d);

            if(!mp[a])
            {
                mp[a] = len++;
            }
            if(!mp[b])
            {
                mp[b] = len++;
            }

            int u = mp[a];
            int v = mp[b];

            head[u].push_back(i);
            edge[i].cost = d;
            edge[i].nod = v;

            head[v].push_back(i+N);
            edge[i+N].cost = d;
            edge[i+N].nod = u;

        }

        queue<int> que;
        int d[160];
        fill(d,d+160,INF);
        d[1] = 0;
        que.push(1);
        bool vis[160]  = {false};
        vis[1] = true;
        while(!que.empty())
        {

            int u = que.front();
            vis[u] = false;
            que.pop();
            for (int i = 0; i < head[u].size(); i++)
            {
                int t = head[u][i];
                if(d[edge[t].nod] > d[u] + edge[t].cost)
                {
                    d[edge[t].nod] = d[u] + edge[t].cost;
                    if(!vis[edge[t].nod])
                    {
                        vis[edge[t].nod] = true;
                        que.push(edge[t].nod);
                    }
                }
            }
        }
        if(flag)
        {
            printf("0\n");
        }
        else
        {
            if(d[2] == INF)
            {
                printf("-1\n");
            }
            else
            {
                printf("%d\n",d[2]);
            }
        }
    }
    return 0;
}

HDU 1217 Arbitrage

这题比较有意思,我一开始不会做,题意大概是,给你N个货币类型,接下来M个货币兑换,问你是否存在一种情况,结果多次兑换后,你可以赚钱,比如一开始美元是1,你换来换去后可以把1美元变成大于1美元的情况...
这题据说不可以用djkstral,因为乘法中,小于1表示有负环,..所以用SPFA来弄,当然Floyd也可以,不过我还并不会...

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
//lower_bound(a+1,a+1+len1,x) - a - 1;
typedef long long LL;

using namespace std;
vector<int>head[40];
struct E
{
    double cost;
    int nod;
}edge[10000];
bool SPFA(int start)
{
    bool vis[40] = {false};
    double d[40] = {0};
    d[start] = 1.0;
    queue<int> que;
    que.push(start);
    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        vis[u] = false;
        for (int i = 0; i < head[u].size(); i++)
        {
            int t = head[u][i];//边
            int v = edge[t].nod;
            double cost = edge[t].cost;
            if(d[v] < d[u]*cost)
            {
                d[v] = d[u]*cost;
                vis[v] = true;
                que.push(v); 
            } 
        }
        
        if(d[start] > 1.0)
        {
            return true;
         } 
    }
    return false;
}
int main()
{
//    freopen("xx.in","r",stdin);
//    freopen("xx.out","w",stdout);
    int N;
    int T = 1;
    while(scanf("%d",&N)!=EOF && N > 0)
    {
        char a[100],b[100];
        memset(edge,0,sizeof(0));
        map<string,int>mp;
        for(int i = 0; i < 40; i++) head[i].clear();
        
        for (int i = 1; i < N + 1; i++)
        {
            scanf("%s",a);
            mp[a] = i;
        }
        int M;
        double cost;
        scanf("%d",&M);
        for (int i = 1; i < M + 1 ; i++)
        {
            scanf("%s %lf %s",a,&cost,b);
            int u = mp[a];
            int v = mp[b];
            
            head[u].push_back(i);
            edge[i].cost = cost;
            edge[i].nod = v;
        }
        bool flag = false;
        for (int i = 1; i < N+1; i++)
        {
            if(SPFA(i))
            {
                flag = true;
                break;
            }
        }
        printf("Case %d: ",T++);
        if(flag) printf("Yes\n");
        else printf("No\n"); 
        
    }
    return 0;
}

HUD 1874畅通工程续

也是裸题

//SPFA
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <stack>
//lower_bound(a+1,a+1+len1,x) - a - 1;
typedef long long LL;

using namespace std;

const int INF = 10000000;
struct E
{
    int to;
    int cost;
};
int main()
{
//    freopen("xx.in","r",stdin);
//    freopen("xx.out","w",stdout);
    int M,N;
    while (scanf("%d %d",&N,&M)!=EOF)
    {    
        E edge[20020];
        vector<int> head[205];
        for(int i = 1 ; i <= M; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            
            head[u].push_back(i);
            edge[i].to = v;
            edge[i].cost = d;
            
            head[v].push_back(i+M);
            edge[i+M].to = u;
            edge[i+M].cost = d;
        }
        int S,T;
        scanf("%d%d",&S,&T);
        int d[205];
        fill(d,d+205,INF);
        d[S] = 0;
        queue<int> que;
        bool vis[205] = {false};
        que.push(S);
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            vis[u] = false;
            for (int i  = 0; i < head[u].size(); i++)
            {
                int v = edge[head[u][i]].to;
                int cost = edge[head[u][i]].cost;
                if(d[v] > d[u] + cost)
                {
                    d[v] = d[u] + cost;
                    if(!vis[v])
                    {
                        vis[v] = true;
                        que.push(v);
                    }
                    
                }
            }
        }
        if(d[T] == INF)
        {
            printf("-1\n");
        }
        else
        {
            printf("%d\n",d[T]);
        }
        
    }
    return 0;
}

HUD 2544最短路

同样裸题

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <stack>
//lower_bound(a+1,a+1+len1,x) - a - 1;
typedef long long LL;

using namespace std;

const int INF = 10000000;
struct E
{
    int to;
    int cost;
};
int main()
{
//    freopen("xx.in","r",stdin);
//    freopen("xx.out","w",stdout);
    int M,N;
    while (scanf("%d %d",&N,&M),M||N)
    {    
        E edge[20020];
        vector<int> head[205];
        for(int i = 1 ; i <= M; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            
            head[u].push_back(i);
            edge[i].to = v;
            edge[i].cost = d;
            
            head[v].push_back(i+M);
            edge[i+M].to = u;
            edge[i+M].cost = d;
        }
        int d[205];
        fill(d,d+205,INF);
        d[1] = 0;
        queue<int> que;
        bool vis[205] = {false};
        que.push(1);
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            vis[u] = false;
            for (int i  = 0; i < head[u].size(); i++)
            {
                int v = edge[head[u][i]].to;
                int cost = edge[head[u][i]].cost;
                if(d[v] > d[u] + cost)
                {
                    d[v] = d[u] + cost;
                    if(!vis[v])
                    {
                        vis[v] = true;
                        que.push(v);
                    }
                    
                }
            }
        }
        printf("%d\n",d[N]);
        
    }
    return 0;
}

更新日志

|时间 | 更新模块 |
|---------------- | ----------- --- |
|6.5 | 3道裸题 |
|6.6 | 1道裸题 |

转载于:https://www.cnblogs.com/Anani-leaf/p/5563433.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值