删边最短路
删边最短路
裸体题洛谷 P1186玛丽卡 P1491集合位置 双倍经验
玛丽卡
跑最短路,求出玛丽卡最短时间,然后标记路径,使最短路径上的路径堵车,枚举每条路径,然后对答案取max
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
#define inf 0x7fffffff
const int N=1010101;
int n,m,head[N],cnt,dis[N],vis[N],numx,numy,ans=0,x[N],y[N],z[N],last[N],las[N];
struct node{
int to,next,dis;
}e[N<<1];
struct edge{
int l,d;
bool operator<(const edge&a)const{return d >a.d;}
};
inline void add(int u,int v,double w){
e[++cnt].next=head[u];
e[cnt].to=v;
e[cnt].dis=w;
head[u]=cnt;
}
priority_queue<edge>q;
void dij(int x){
for(int i = 1;i <= n;i++) dis[i] = inf,vis[i]=0;
dis[x] = 0;
q.push((edge){x,0});
while(!q.empty()){
edge p = q.top();
q.pop(); int u = p.l;
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if((numx == v && numy == u) || (numx == u && numy == v)) continue;
if(dis[v] > dis[u] + e[i].dis){
dis[v] = dis[u] + e[i].dis;
last[v] = u;
q.push((edge){v,dis[v]});
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
int x,y,z;
for(int i = 1;i <= m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dij(1);
for(int i = 1;i <= n;i++) las[i] = last[i];
int f = n;
while(f != 0){
numx = f; numy = las[f];
dij(1);
ans = max(dis[n],ans);
f = las[f];
}
printf("%d",ans);
}
集合位置
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
#define maxn 300
using namespace std;
#define M(x,y) make_pair(x,y)
int fr[1000010],to[2000010],next[2000010],tl,f[4100010];
double d[1000010],v[2000010];
int x[100101],y[100100];
bool b[1000010];int cnt,flag;
double num(int i,int j){return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}
int inf=0x3f3f3f3f;
int per[1000000];
void add(int x,int y,double w){
to[++tl]=y;
v[tl]=w;
next[tl]=fr[x];
fr[x]=tl;
f[tl]=x;
}
inline void read(int &x){
x=0;int f(0);char ch(getchar());
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=f?-x:x;
}
int n,m,z,s;
void dij(int dd,int bb)
{
memset(b,0,sizeof(b));
priority_queue< pair<int,int> > q;
int s=1;
for(int i=1;i<=n;i++) d[i]=123123123;
d[s]=0;
q.push(M(0,s));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(b[x]) continue;
b[x]=1;
for(int i=fr[x];i;i=next[i])
{
int y=to[i];
if((x==dd&&y==bb)||(x==bb&&y==dd)) continue;
double l=v[i];
if(d[y]>d[x]+l){
d[y]=d[x]+l;
if(!flag||dd==-1&&bb==-1)
per[y]=x;
q.push(M(-d[y],y));
}
}
}
}
int main()
{
read(n),read(m);
for(int i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<m;i++){
int x,y;
scanf("%d%d",&x,&y);
double z=num(x,y);
add(x,y,z);
add(y,x,z);
}
dij(-1,-1);
flag=1;
double ans=inf;
int now=n;
while(per[now]){
dij(per[now],now);
ans=min(d[n],ans);
now=per[now];
}
if(ans==inf)printf("-1\n");
printf("%.2lf",ans);
}