删边最短路

删边最短路

裸体题洛谷 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);
}

P2685 [TJOI2012]桥 以后补坑

猜你喜欢

转载自www.cnblogs.com/shikeyu/p/13399320.html