现世斩

Description

给出一个n个点,m条边的无向图。你可以选择一个点x,把x相连得边边权变为1.求1~n的最短路。
n<=10^5,m<=n*5

Solution

辣鸡出题人,卡我空间。
很多神奇的做法,你可以直接分层,然后一边最短路。
或者两边最短路,然后枚举修改的点。
随便乱搞一下就好啦!!

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=last[a];i;i=next[i])
#define N 300005
#define M 8000005
using namespace std;
typedef long long ll;
int n,m,x,y,z,l;
int t[M],next[M],d[M],v[M],last[N];
ll dis[N],ans;
bool bz[N];
void add(int x,int y,ll z) {
    t[++l]=y;v[l]=z;next[l]=last[x];last[x]=l;
}
void spfa() {
    memset(dis,127,sizeof(dis));dis[1]=0;
    memset(bz,0,sizeof(bz));bz[1]=1;
    int i=0,j=1;d[1]=1;
    while (i<j) {
        rep(k,d[++i]) if (dis[t[k]]>dis[d[i]]+v[k]) {
            dis[t[k]]=dis[d[i]]+v[k];
            if (!bz[t[k]]) bz[t[k]]=1,d[++j]=t[k];
        }
        bz[d[i]]=0;
    }
}
int main() {
    freopen("cut.in","r",stdin);
    freopen("cut.out","w",stdout);
    scanf("%d%d",&n,&m);
    fo(i,1,m) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
        add(x,y+n,1);add(y,x+n,1);
        add(x+n,y+2*n,1);add(y+n,x+2*n,1);
        add(x+2*n,y+2*n,z);add(y+2*n,x+2*n,z);
    }
    spfa();printf("%lld",min(dis[3*n],dis[2*n]));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值