SDUT 周赛 2493 A Constructing Roads 最短路

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2493

题意:

给定一个图,给出起点s,终点e 求从起点到终点的最短距离。这里我们允许从其中任意选择一条路径长度减半(这样的处理只能针对一条边)。

思路:

才开始思路是先求出最短路径,然后取最短路径上的路径的最大权值取一半。结果wa致死。。。后来思考才知道思路错了。

这样不能保证最有,可能由起点到终点的一条不在最短路上的路径直接取半就是最优的。 

正确的处理方法是:两遍最短路,分别求出S到所有点的最短路,E到所有点的最短路。然后枚举每条边取半的情况取最小值即可。

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a,b) (a) > (b)? (b):(a)

#define Max(a,b) (a) > (b)? (a):(b)



#define ll long long

#define inf 0x7f7f7f7f

#define MOD 1073741824

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 50007

#define N 1007

using namespace std;

//freopen("din.txt","r",stdin);



struct node

{

    int v,w;

    int next;

}g[M*2];

int head[N],ct;



int dis1[N],dis2[N];

int vt[N];

int n,m;



void add(int u,int v,int w)

{

    g[ct].v = v;

    g[ct].w = w;

    g[ct].next = head[u];

    head[u] = ct++;

}



void spfa1(int s)

{

    int i;

    for (i = 1; i <= n; ++i)

    {

        dis1[i] = inf;

        vt[i] = false;

    }

    queue<int>q;

    q.push(s); dis1[s] = 0;

    vt[s] = true;

    while (!q.empty())

    {

        int u = q.front(); q.pop();

        vt[u] = false;

        for (i = head[u]; i != -1; i = g[i].next)

        {

            int v = g[i].v;

            int w = g[i].w;

            if (dis1[v] > dis1[u] + w)

            {

                dis1[v] = dis1[u] + w;

                if (!vt[v])

                {

                    vt[v] = true;

                    q.push(v);

                }

            }

        }

    }

}



void spfa2(int s)

{

    int i;

    for (i = 1; i <= n; ++i)

    {

        dis2[i] = inf;

        vt[i] = false;

    }

    queue<int>q;

    q.push(s); dis2[s] = 0;

    vt[s] = true;

    while (!q.empty())

    {

        int u = q.front(); q.pop();

        vt[u] = false;

        for (i = head[u]; i != -1; i = g[i].next)

        {

            int v = g[i].v;

            int w = g[i].w;

            if (dis2[v] > dis2[u] + w)

            {

                dis2[v] = dis2[u] + w;

                if (!vt[v])

                {

                    vt[v] = true;

                    q.push(v);

                }

            }

        }

    }

}

int main()

{

    //freopen("din.txt","r",stdin);

    int i,j,x,y,w;

    while (~scanf("%d%d",&n,&m))

    {

        CL(head,-1); ct = 0;

        for (i = 0; i < m; ++i)

        {

            scanf("%d%d%d",&x,&y,&w);

            add(x,y,w);

            add(y,x,w);

        }

        int s,e;

        scanf("%d%d",&s,&e);

        spfa1(s);

        if (dis1[e] == inf)

        {

            printf("No solution\n");

            continue;

        }



        spfa2(e);

        int MIN = inf;

        for (i = 1; i <= n; ++i)

        {

            for (j = head[i]; j != -1; j = g[j].next)

            {

                int v = g[j].v;

                int w = g[j].w;

                if (dis1[i] != inf && dis2[v] != inf)

                MIN = min(MIN,dis1[i] + dis2[v] + w/2);

                if (dis2[i] != inf && dis1[v] != inf)

                MIN = min(MIN,dis2[i] + dis1[v] + w/2);

            }

        }

        printf("%d\n",MIN);

    }

    return 0;

}

  

你可能感兴趣的:(struct)