题目链接:https://cn.vjudge.net/problem/HDU-6582.
题意,给你一个有向图,一个人要从1到n走一条最短的路,可是Tom想让他走的更长一点,所以需要阻断一些路
问 用最少的cost使得这个人走的更长,输出这个cost
思路:就是找到所有的最短路,然后用这个最短路建图,从1到n跑最大流(即最小割)输出结果即可
注意:数据需要long long
这题和HDU-5889 Barricade思路一样
#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define ll long long
using namespace std;
const ll INF = 1e17;
const int MAXN = 40005;
int N,M;
int u,v;
ll w;
struct Edge{
int to ,rev;
ll value;
Edge() {}
Edge(int a,ll b,int c):to(a),value(b),rev(c) {}
};
struct node1{
int v,next;
ll w;
}edge[MAXN];
vector<Edge> E[MAXN];
int deep[MAXN];
int iter[MAXN],head[MAXN];
int id;
void add(int u,int v,ll w){
edge[id].v=v;
edge[id].w=w;
edge[id].next=head[u];
head[u]=id++;
}
inline void Add(int from,int to,ll value){
E[from].push_back(Edge(to,value,E[to].size()));
E[to].push_back(Edge(from,0,E[from].size()-1));
}
bool BFS(int root,int target) {
memset(deep,-1,sizeof deep);
queue<int> Q;
deep[root] = 0;
Q.push(root);
while(!Q.empty())
{
int t = Q.front();
Q.pop();
for(int i=0 ; i<E[t].size() ; i++)
{
if(E[t][i].value > 0 && deep[E[t][i].to] == -1)
{
deep[E[t][i].to] = deep[t] + 1;
Q.push(E[t][i].to);
}
}
}
return deep[target] != -1;
}
ll DFS(int root,int target,ll flow){
if(root == target) return flow;
for(int &i=iter[root] ; i<E[root].size() ; i++)
{
if(E[root][i].value>0 && deep[E[root][i].to] == deep[root]+1)
{
ll nowflow = DFS(E[root][i].to,target,min(flow,E[root][i].value));
if(nowflow > 0)
{
E[root][i].value -= nowflow;
E[E[root][i].to][E[root][i].rev].value += nowflow;
return nowflow;
}
}
}
return 0;
}
bool vis[MAXN];
ll dist[MAXN];
void spfa(int s){
memset(vis,0,sizeof(vis));
for(int i=0;i<=N+10;i++)dist[i]=INF;
vis[s]=1;
dist[s]=0;
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if (dist[v]>dist[u]+edge[i].w){
dist[v]=dist[u]+edge[i].w;
if (!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
int Dinic(int root,int target){
ll sumflow = 0;
while(BFS(root,target)) {
memset(iter,0,sizeof iter);
ll mid;
while(mid=DFS(root,target,INF))sumflow += mid;
}
return sumflow;
}
void init(){
memset(head,-1,sizeof(head));
id=0;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d",&N,&M);
init();
for(int i=0 ; i< M ; i++){
scanf("%d %d %lld",&u,&v,&w);
add(u, v,w);
}
spfa(1);
for(int i = 1; i <= N; ++i) {
for(int j = head[i]; ~j; j = edge[j].next) {
int v = edge[j].v;
if(dist[v] - dist[i] == edge[j].w) {
Add(i, v, edge[j].w);
}
}
}
printf("%lld\n",Dinic(1,N));
for (int i = 0; i <= 12000;i++) E[i].clear();
}
return 0;
}