给你一张图,你可以堵上一条边,代价就是这条边在长度,问你如何用最小的代价使得1->n不能走最短路!
首先我们正反跑两次SPFA,求出那条边在最短路上,然后把这些边扔进最大流里,跑个最小鸽就好了。
HDU 6582
#include
#include
#include
#include
#define int long long
const int inf=0x7fffffff;
const int maxm=1e5+100;
int n,m;
struct node{
int u,v,c;
}a[maxm];
namespace maxflow{
int cnt=1;
int head[maxm],net[maxm*2],to[maxm*2],cap[maxm*2];
std::queue dl;
int deep[maxm];
inline void clear()
{
memset(head,0,sizeof(head));
cnt=1;
}
inline void addedge(int u,int v,int c)
{
cnt++;
to[cnt]=v,cap[cnt]=c,net[cnt]=head[u],head[u]=cnt;
cnt++;
to[cnt]=u,cap[cnt]=0,net[cnt]=head[v],head[v]=cnt;
}
inline bool BFS(int s,int t)
{
memset(deep,-1,sizeof(deep));
dl.push(s);
deep[s]=0;
while(!dl.empty())
{
int now=dl.front();
dl.pop();
for(int i=head[now];i;i=net[i])
if(cap[i]&&deep[to[i]]==-1)
deep[to[i]]=deep[now]+1,dl.push(to[i]);
}
return deep[t]!=-1;
}
int DFS(int now,int flow,int t)
{
if(now==t) return flow;
int used=0,w;
for(int i=head[now];i;i=net[i])
if(cap[i]&&deep[to[i]]==deep[now]+1)
{
w=DFS(to[i],std::min(cap[i],flow-used),t);
used+=w;
cap[i]-=w,cap[i^1]+=w;
if(flow==used) return used;
}
if(!used) deep[now]=-1;
return used;
}
inline int Dinic(int s,int t)
{
int ans=0;
while(BFS(s,t)) ans+=DFS(s,inf,t);
return ans;
}
}
struct SPFA{
int head[maxm],to[maxm*2],net[maxm*2],cost[maxm*2],dis[maxm];
int cnt;
bool vis[maxm];
std::queue dl;
inline void clear()
{
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
cnt=0;
}
inline void addedge(int u,int v,int c)
{
to[++cnt]=v,cost[cnt]=c,net[cnt]=head[u],head[u]=cnt;
}
inline bool BFS(int s,int t)
{
memset(dis,127,sizeof(dis));
dl.push(s);
dis[s]=0,vis[s]=1;
while(!dl.empty())
{
int now=dl.front();
dl.pop();
vis[now]=0;
for(int i=head[now];i;i=net[i])
if(dis[to[i]]>dis[now]+cost[i])
{
dis[to[i]]=dis[now]+cost[i];
if(!vis[to[i]]) dl.push(to[i]),vis[to[i]]=1;
}
}
return dis[t]==dis[0];
}
}spfa[2];
inline int work()
{
maxflow::clear();
spfa[0].clear();
spfa[1].clear();
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,c;
scanf("%lld%lld%lld",&u,&v,&c);
a[i]=(node){u,v,c};
spfa[0].addedge(u,v,c);
spfa[1].addedge(v,u,c);
}
if(spfa[0].BFS(1,n)) return 0;
spfa[1].BFS(n,1);
int dis=spfa[0].dis[n];
for(int i=1;i<=m;i++)
if((spfa[0].dis[a[i].u]+spfa[1].dis[a[i].v]+a[i].c)==dis) maxflow::addedge(a[i].u,a[i].v,a[i].c);
return maxflow::Dinic(1,n);
}
signed main()
{
int t;
scanf("%lld",&t);
for(int i=1;i<=t;i++) printf("%lld\n",work());
return 0;
}