bzoj3258: 秘密任务 (+一百题感言?)

bzoj3258: 秘密任务 题意:n<=400个点,m<=4000条边,可以在每条边的起点或终点截断这条边。求截断所有1到n最短路径的最小花费,以及方案是否唯一。显然是个最小割的模型。按照题意跑一遍最短路,把不在最短路里的边删掉,其他的拆成两条边,流量分别赋起点和终点的费用,跑最大流,第一问结束。有关最小割是否有唯一方案,参考了这个blog↓
摘要由CSDN通过智能技术生成

bzoj3258: 秘密任务
题意:n<=400个点,m<=4000条边,可以在每条边的起点或终点截断这条边。求截断所有1到n最短路径的最小花费,以及方案是否唯一。


题解

显然是个最小割的模型。
按照题意跑一遍最短路,把不在最短路里的边删掉,其他的拆成两条边,流量分别赋起点和终点的费用,跑最大流,第一问结束。
有关最小割是否有唯一方案,参考了这个blog↓
[BZOJ 1797][BZOJ 3258]最小割的唯一性判定
跑一遍tarjan对于一条满流边。如果起点与终点分属两个scc,那么它可以作为原图最小割的一条边。而当起点与S所在scc相同,终点与T所在scc相同时,这条边的选择是唯一的。


代码

说起来是时隔半年后第一次上3000B呢。
交完去吃饭,回来发现1A了,还是很开心的。

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 5000
#define M 24006
#define ll long long
using namespace std;
int T,n,m,n_,a[N];
int to[M],hd[M],val[M],lk[N],cur[N];
char ch;
int q[N],h,t,dfn[N],low[N],tms;
bool inq[N];
ll dis[N],ans;
void add(int u,int v,int w,int loc)
{to[loc]=v,hd[loc]=lk[u],val[loc]=w,lk[u]=loc;}
void read(int &x)
{
    x=0;
    do ch=getchar();
    while(ch<'0'||ch>'9');
    do x=x*10+ch-'0',ch=getchar();
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值