题目大意
有一个 个点的有向图,一个人要从 出发去 ,现在突发了一个事故,毁坏了一条道路,但是这个人只有走到这个道路的起点,他才会知道道路被毁坏了。求在最坏情况下的最短路。
思路
原文的英文真是说的稀里糊涂。题目大意也好容易才翻译出来。。。
拿到这个题不是很有思路的。
首先预处理出一个
代表在
节点时,若有一条边被损坏,最坏情况下到达
号点的最短路(有点混乱是不是。。。)
怎么求bad呢?注意到n很小,枚举每一条边,将它删去跑Dijkstra即可。
然后考虑怎么求答案。
我们先假装这个图是一个DAG,就可以DP,
表示
号点到达
号点的最坏情况下的最短路。如何转移呢?分两种情况。
- 这个人在这里碰到了坏边:
- 这个人继续往前走,并在接下来的路程上才碰到坏边:
这两个取max即可。
但是这不是一个DAG,那就考虑SPFA/Dijkstra转移DP。把松弛的条件改成
就行了呢。。。
用老师的话说:最短路裸题
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<cctype>
#define pa pair<int,int>
#define INF 0x3f3f3f3f
#define inf 0x3f
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pb push_back
using namespace std;
inline ll read()
{
long long f=1,sum=0;
char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-1;c=getchar();}
while (isdigit(c)) {sum=sum*10+c-'0';c=getchar();}
return sum*f;
}
const int MAXN=110;
const int MAXM=2510;
struct edge{
int next,to,val,id;
}e[MAXM];
int head[MAXN],cnt;
void addedge(int u,int v,int w,int id)
{
e[++cnt].next=head[u];
e[cnt].to=v;
e[cnt].val=w;
e[cnt].id=id;
head[u]=cnt;
}
struct Map{
int u,v,w;
}M[MAXM];
int dis[MAXN];
bool visit[MAXN];
priority_queue <pa,vector<pa>,greater<pa> > q;
void Dijkstra(int s,int ban)
{
memset(dis,inf,sizeof(dis));
memset(visit,0,sizeof(visit));
dis[s]=0;
q.push(mp(0,s));
while (!q.empty())
{
int x=q.top().se;
q.pop();
if (visit[x]) continue;
visit[x]=1;
for (int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if (e[i].id==ban) continue;
if (dis[v]>e[i].val+dis[x])
dis[v]=dis[x]+e[i].val,q.push(mp(dis[v],v));
}
}
}
#define piii pair<pa,int>
int st;
piii get_num(string s)
{
int pos1=0;
for (int i=st;!pos1;i++)
if (s[i]==' ')
pos1=i;
piii re;
for (int i=st;i<pos1;i++)
re.fi.fi=re.fi.fi*10+s[i]-'0';
int pos2=0;
for (int i=pos1+1;!pos2;i++)
if (s[i]==' ')
pos2=i;
for (int i=pos1+1;i<pos2;i++)
re.fi.se=re.fi.se*10+s[i]-'0';
int pos3=0;
for (int i=pos2+1;!pos3&&i<s.size();i++)
if (s[i]==',')
pos3=i;
if (!pos3) pos3=s.size();
for (int i=pos2+1;i<pos3;i++)
re.se=re.se*10+s[i]-'0';
st=pos3+1;
return re;
}
int bad[MAXN],f[MAXN];
void get_ans()
{
memset(f,inf,sizeof(f));
memset(visit,0,sizeof(visit));
f[2]=0;
q.push(mp(0,2));
while (!q.empty())
{
int x=q.top().se;
q.pop();
if (visit[x]) continue;
visit[x]=1;
for (int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if (max(bad[v],f[x]+e[i].val)<f[v])
f[v]=max(bad[v],f[x]+e[i].val),q.push(mp(f[v],v));
}
}
}
struct WarTransportation{
int messenger(int n,vector<string> highways)
{
string str;str.clear();
str=highways[0];
int m=highways.size();
for (int i=1;i<m;i++)
str=str+highways[i];
int ids=1;
m=str.size();
while (st<m)
{
piii Edge=get_num(str);
M[ids].u=Edge.fi.fi,M[ids].v=Edge.fi.se,M[ids].w=Edge.se;
addedge(Edge.fi.fi,Edge.fi.se,Edge.se,ids);
ids++;
}
m=ids-1;
for (int i=1;i<=m;i++)
{
if (M[i].u==2) continue;
Dijkstra(M[i].u,i);
bad[M[i].u]=max(bad[M[i].u],dis[2]);
}
memset(head,0,sizeof(head));cnt=0;
for (int i=1;i<=m;i++)
addedge(M[i].v,M[i].u,M[i].w,i);
get_ans();
return f[1]>=INF?-1:f[1];
}
};