HDU2485 Destroying the bus stations(floyd+最大流)

本文介绍了一种利用网络流算法解决特定图论问题的方法——即如何通过最少的公交站破坏使军队无法在限定时间内从军营到达机场。文章详细阐述了问题背景及求解思路,包括使用Floyd算法进行预处理以及在网络流模型中巧妙地添加边来表示限制条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意一个图,每条边权值为1,其中毁坏多少个点可以使得从1到n至少要花费k+1的时间

思路:首先求一次floyd,如果从1到n原本就需要大于k的时间那么输出0即可,如果小于的话,那么就在最短路径上选择d[1][k]+d[k][n]<k的路径来添加进网络流,因为如果两点路径本来大于k的话删除也没用。因为每条边走一次那么不难想到拆点了,一个表示进,一个表示出,和平常题目一样连边,跑一遍最大流即可

吐槽:这题WA了无数次,尝试了各种姿势,最后瞎改了maxn为10010,就过了,一开始我写的是1200...可是题目写的n不是最大是50么..那么我拆点最多不也才100个点...gg...

          另外做完搜了一下题解...发现这道题用网络流是有缺陷的...正解应该是迭代加深搜索..gg...


#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 10010
#define INF 1e9
#define LL long long
int cas=1,T;
struct Edge
{
	int from,to,cap,flow;
	Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
int n,m;
struct Dinic
{
//	int n,m;
    int s,t;
	vector<Edge>edges;        //边数的两倍
	vector<int> G[maxn];      //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
	bool vis[maxn];           //BFS使用
	int d[maxn];              //从起点到i的距离
	int cur[maxn];            //当前弧下标
	void init()
	{
	   for (int i=0;i<=2*n+1;i++)
		   G[i].clear();
	   edges.clear();
	}
	void AddEdge(int from,int to,int cap)
	{
		edges.push_back(Edge(from,to,cap,0));
		edges.push_back(Edge(to,from,0,0));        //反向弧
		int mm=edges.size();
		G[from].push_back(mm-2);
		G[to].push_back(mm-1);
	}
	bool BFS()
	{
		memset(vis,0,sizeof(vis));
		queue<int>q;
		q.push(s);
		d[s]=0;
		vis[s]=1;
		while (!q.empty())
		{
			int x = q.front();q.pop();
			for (int i = 0;i<G[x].size();i++)
			{
				Edge &e = edges[G[x][i]];
				if (!vis[e.to] && e.cap > e.flow)
				{
					vis[e.to]=1;
					d[e.to] = d[x]+1;
					q.push(e.to);
				}
			}
		}
		return vis[t];
	}

	int DFS(int x,int a)
	{
		if (x==t || a==0)
			return a;
		int flow = 0,f;
		for(int &i=cur[x];i<G[x].size();i++)
		{
			Edge &e = edges[G[x][i]];
			if (d[x]+1 == d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
			{
				e.flow+=f;
				edges[G[x][i]^1].flow-=f;
				flow+=f;
				a-=f;
				if (a==0)
					break;
			}
		}
		return flow;
	}

	int Maxflow(int s,int t)
	{
		this->s=s;
		this->t=t;
		int flow = 0;
		while (BFS())
		{
			memset(cur,0,sizeof(cur));
			flow+=DFS(s,INF);
		}
		return flow;
	}
}dc;

int d[60][60];
void floyd()
{
	for (int k = 1;k<=n;k++)
		for (int i = 1;i<=n;i++)
			for (int j = 1;j<=n;j++)
				if (d[i][k]<INF && d[k][j]<INF&&i!=j)
					d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
int a[maxn];
int b[maxn];
int main()
{
	int kk;
	while (scanf("%d%d%d",&n,&m,&kk) && n+m+kk)
	{
		dc.init();
		for (int i = 1;i<=n;i++)
			for (int j = 1;j<=n;j++)
				if (i!=j)
					d[i][j]=INF;
		        else
					d[i][j]=0;
        for (int i = 1;i<=m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			d[u][v]=1;
//			dc.AddEdge(u+n,v,1);
		}
		int pos=0;
		for (int i = 1;i<=n;i++)
		{
           for (int j = 1;j<=n;j++)
			   if (d[i][j]==1)
			   {
				   a[pos]=i;
                   b[pos++]=j;
			   }
		}
		floyd();
		if (d[1][n]>kk)
		{
			printf("0\n");
			continue;
		}
		else{
		for (int i = 0;i<pos;i++)
		{
			if (d[1][a[i]]+d[b[i]][n] < kk)
				dc.AddEdge(a[i]+n,b[i],INF);
		}
		for (int i = 1;i<=n;i++)
			dc.AddEdge(i,i+n,1);
		int ans = dc.Maxflow(n+1,n);
    	printf("%d\n",ans);

		}
	}
}

Description

Gabiluso is one of the greatest spies in his country. Now he’s trying to complete an “impossible” mission ----- to make it slow for the army of City Colugu to reach the airport. City Colugu has n bus stations and m roads. Each road connects two bus stations directly, and all roads are one way streets. In order to keep the air clean, the government bans all military vehicles. So the army must take buses to go to the airport. There may be more than one road between two bus stations. If a bus station is destroyed, all roads connecting that station will become no use. What’s Gabiluso needs to do is destroying some bus stations to make the army can’t get to the airport in k minutes. It takes exactly one minute for a bus to pass any road. All bus stations are numbered from 1 to n. The No.1 bus station is in the barrack and the No. n station is in the airport. The army always set out from the No. 1 station. 
No.1 station and No. n station can’t be destroyed because of the heavy guard. Of course there is no road from No.1 station to No. n station. 


Please help Gabiluso to calculate the minimum number of bus stations he must destroy to complete his mission. 
 

Input

There are several test cases. Input ends with three zeros. 

For each test case: 

The first line contains 3 integers, n, m and k. (0< n <=50, 0< m<=4000, 0 < k < 1000) 
Then m lines follows. Each line contains 2 integers, s and f, indicating that there is a road from station No. s to station No. f. 
 

Output

For each test case, output the minimum number of stations Gabiluso must destroy.
 

Sample Input

5 7 3 1 3 3 4 4 5 1 2 2 5 1 4 4 5 0 0 0
 

Sample Output

2
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值