传送门:HDU 5889 Barricade
已知敌方会选择最短路来己方。要选择一些路设障碍,让敌方至少碰到一个障碍。
先跑一个最短路。
对于每一条边u-v,如果dis[v]==dis[u]+1
这条路就可能在最短路中。
然后跑个最小割(其实是最大流)
为什么酱紫保证正确呢?刚开始我也有怀疑是水数据。。
后来想了想如果不是最短路中的边,肯定无法跑到终点,至少会有一处断开。所以大胆跑最小割就行了
#include
#include
#include
#include
#include
#include
using namespace std;
/*vector建图
点很多的话效率会比较低
*/
const int inf=0x3f3f3f3f;
const int maxn=1005;
const int maxm=10005;//边数的最大值
vector >E[maxn];//邻接表
int n,m;
int dis[maxn],inq[maxn];
void init(){
for(int i=0; i >q;
dis[s]=0;
q.push(make_pair(-dis[s],s));//优队返回的是最大值,取负就返回的最小值
while(!q.empty()){
int now=q.top().second;
q.pop();inq[now]=0;
for(int i=0; idis[now]+E[now][i].second){
dis[v]=dis[now]+E[now][i].second;
q.push(make_pair(-dis[v],v));
}
}
}
}
//最大流求最小割
/*ISAP+bfs初始化+栈优化
*/
struct Edge {
int to,next,cap,flow;
}edge[maxm];//注意是maxm
int tol;
int head[maxn];
int cur[maxn],d[maxn];// 当前弧下标 结点到汇点距离下界
int p[maxn],gap[maxn];//可增广路上的上一条弧 gap优化 //比dinic多的两个数组
void init1(){
tol=0;
memset(head, -1, sizeof(head));
}
void addedge(int u,int v,int w,int rw = 0){
edge[tol].to=v; edge[tol].cap=w; edge[tol].flow=0;
edge[tol].next=head[u]; head[u]=tol++;
edge[tol].to=u; edge[tol].cap=rw; edge[tol].flow=0;
edge[tol].next=head[v]; head[v]=tol++;
}
int Q[maxn];
void bfs(int s,int t){//逆向进行bfs
memset(d, -1, sizeof(d));
memset(gap, 0, sizeof(gap));
gap[0]=1;
int front=0, rear=0;
d[t]=0;
Q[rear++]=t;
while(front!=rear){
int u=Q[front++];
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].to;
if(d[v]!=-1)continue;
Q[rear++]=v;
d[v]=d[u]+1;
gap[d[v]]++;
}
}
}
int S[maxn];
//输入参数:起点、终点、点的总数
//点的编号没有影响,只要输入点的总数
int sap(int s,int t,int N){
bfs(s, t);
memcpy(cur, head, sizeof(head));
int top=0;
int u=s;
int ans=0;
while(d[s]edge[S[i]].cap-edge[S[i]].flow){
Min=edge[S[i]].cap-edge[S[i]].flow;
inser=i;
}
for(int i=0; ival[maxn];
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0; i<=n; i++)val[i].clear();
init();
for(int i=1; i<=m; i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
E[u].push_back(make_pair(v, 1));
E[v].push_back(make_pair(u, 1));
val[u].push_back(w);
val[v].push_back(w);
}
dijkstra(1, n);
init1();
for(int u=1; u<=n; u++){
for(int i=0; i