【洛谷1186】玛丽卡 图论最短路

分析

枚举所有的边,把这一条边去掉,在跑n遍最短路。
设置del[x][y]$$成一个删除数组,每次在spfa更新最短路的时候,在加一个判断是否被删除。

AC代码

#include<bits/stdc++.h>
using namespace std;
struct str{
    int from,to,next,v;
}e[2000005];
int n,m,ans,cnt,head[1005],q[10000005],dist[1005],father[1005];
bool inq[1005],del[1005][1005];
   
void add(int a,int b,int w){
    cnt++;
    e[cnt].from=a;
    e[cnt].to=b;
    e[cnt].v=w;
    e[cnt].next=head[a];
    head[a]=cnt;
} 
   
void spfa(int k){
    memset(dist,127,sizeof(dist));
    memset(inq,0,sizeof(inq));
    int t=0,w=1,now;
    q[t]=1;
    inq[1]=1;
    dist[1]=0;
    while(t<w){
        int p=head[q[t]];
        now=q[t];
        t++;
        while(p){
              
            if(!del[now][e[p].to]&&dist[now]+e[p].v<dist[e[p].to]){
                dist[e[p].to]=dist[now]+e[p].v;
                if(k==1) father[e[p].to]=now; 
                if(!inq[e[p].to]){
                    inq[e[p].to]=1;
                    q[w++]=e[p].to;
                }
            }
            p=e[p].next;
        }
        inq[now]=0;
    }
}
   
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z); 
        add(x,y,z);
        add(y,x,z);
    }
    spfa(1);
    ans=dist[n];
    for(int i=n;i!=1;i=father[i]){
        del[father[i]][i]=del[i][father[i]]=1; 
        spfa(0);
        del[father[i]][i]=del[i][father[i]]=0;
        ans=max(dist[n],ans);
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Dawn-Star/p/9712487.html