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;
}


浙公网安备 33010602011771号