1. 程式人生 > >題解 LuoguP2299 【Mzc和體委的爭奪戰】

題解 LuoguP2299 【Mzc和體委的爭奪戰】

size set priority clas || gcc != using oid

最短路裸題,分SPFA和dijkstra兩種做法。

SPFA:

#pragma GCC diagnostic error "-std=c++11"
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define inf 99999999
using namespace std;
template<class T>void r(T &a)//快讀
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}
int first[2510],next[400010];
int u[400010],v[400010],w[400010],dis[2510];
bool book[2510];
int n,m;
void add(int U,int V,int W,int i)//存邊
{
    u[i]=U;v[i]=V;w[i]=W;
    next[i]=first[U];first[U]=i;
}
void spfa(int i)//spfa
{
    for(int j=1;j<=n;j++)
        dis[j]=inf;
    dis[i]=0;
    memset(book,false,sizeof(book));
    queue<int>q;
    q.push(i);
    book[i]=true;
    while(!q.empty())
    {
        int k=first[q.front()];
        while(k!=-1)//遍歷q.front()的所有子節點
        {
            if(dis[v[k]]>dis[u[k]]+w[k])//松弛
            {
                dis[v[k]]=dis[u[k]]+w[k];
                if(book[v[k]]==false)
                {
                    q.push(v[k]);
                    book[v[k]]=true;
                }
            }
            k=next[k];
        }
        book[q.front()]=false;
        q.pop();
    }
}
int main()
{
    r(n,m);
    for(int i=1;i<=n;i++)
        first[i]=-1;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        r(a,b,c);
        add(a,b,c,i);//存無向邊
        add(b,a,c,i+m);
    }
    spfa(1);
    printf("%d",dis[n]);
    return 0;
}

dijkstra:

#pragma GCC diagnostic error "-std=c++11"
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define inf 99999999
using namespace std;
template<class T>void r(T &a)//快讀
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}
int first[2510],next[400010];
int u[400010],v[400010],w[400010],dis[2510];
bool book[2510];
int n,m;
void add(int U,int V,int W,int i)//存邊
{
    u[i]=U;v[i]=V;w[i]=W;
    next[i]=first[U];first[U]=i;
}
void dijkstra(int i)//dijkstra
{
    for(int j=1;j<=n;j++)
        dis[j]=inf;
    dis[i]=0;
    memset(book,false,sizeof(book));
    priority_queue<pair<int,int> >q;
    q.push(make_pair(0,i));
    while(!q.empty())
    {
        int x=q.top().second;
        q.pop();
        if(book[x])continue;
        book[x]=true;
        for(int k=first[x];k;k=next[k])//遍歷x的所有子節點
        {
            if(dis[v[k]]>dis[u[k]]+w[k])//松弛
            {
                dis[v[k]]=dis[u[k]]+w[k];
                q.push(make_pair(-dis[v[k]],v[k]));
            }
        }
    }
}
int main()
{
    r(n,m);
    for(int i=1;i<=n;i++)
        first[i]=-1;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        r(a,b,c);
        add(a,b,c,i);//存無向邊
        add(b,a,c,i+m);
    }
    dijkstra(1);
    printf("%d",dis[n]);
    return 0;
}

題解 LuoguP2299 【Mzc和體委的爭奪戰】