poj3921.Destroying the bus stations( 迭代加深搜索 && BFS )

有一张 n 个点, m 条边的有向图,要你删除最少的点使得 1 -> 的路径长度大于 k ,两点之间路径长均为 号点和 n 号点不能被删除。

因为数据规模比较小,直接搜索(迭代加深),枚举删除的点数同时也作为深度,先 BFS 找到一条从 1 到 的路径,然后依次删除上面的点,分别进行 BFS 再次寻找路径,看能否大于k。

#include <cstdio>
#include <cstring>

using namespace std;

const int MAX_N = 100;
const int MAX_M = 4005;

struct node{
	int v, next;
}E[MAX_M];
int head[MAX_N], top = 0;

inline void add(int u, int v)
{
	E[++ top].v = v; E[top].next = head[u]; head[u] = top;
}

int n, m, k, id, to[MAX_N], q[MAX_N], arr[MAX_N][MAX_N];
bool got = 0, vis[MAX_N];

void init()
{
	for(int i = 1; i <= m; i ++){
		int u, v; scanf("%d%d", &u, &v);
		add(u, v);
	}
}

void bfs()
{
	memset(to, 0, sizeof(to));
	int begin = 0, end = 1;
	q[begin] = 1;
	while(begin < end){
		int x = q[begin];
		for(int i = head[x]; i; i = E[i].next)
			if(!vis[E[i].v] && to[E[i].v] == 0){
				to[E[i].v] = x; q[end] = E[i].v;
				end ++;
				if(E[i].v == n) break;
			}
		begin ++;
		if(to[n]) break;
	}
}

void dfs(int deep)
{
	if(got) return;
	bfs();
	if(to[n] == 0){ got = 1;  return; }
	int v = n, tot = -1;
	while(v){
		arr[deep][++ tot] = v;
		v = to[v];
	}
	if(tot > k){ got = 1; return; }
	if(deep > id) return;
	for(int i = 1; i < tot; i ++){
		vis[arr[deep][i]] = 1;
		dfs(deep + 1);
		vis[arr[deep][i]] = 0;
	}
}

void doit()
{
	int ans = -1; got = 0;
	for(int i = 0; i <= n; i ++){
		id = i; memset(vis, 0, sizeof(vis));
		dfs(1);
		if(got) { ans = i; break; }
	}
	if(ans != -1)printf("%d\n", ans);
	else printf("%d\n", n);
}

int main()
{
	freopen("1.in", "r", stdin);
	while(scanf("%d%d%d", &n, &m, &k) != EOF){
		if(n == 0 && m == 0 && k == 0) break;
		memset(head, 0, sizeof(head)); top = 0;
		init(); doit();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值