CF 543B 圖,最短路

題目鏈接:http://codeforces.com/problemset/problem/543/B


題意:總共有n個點(1<= n<=3000),m條邊(m <= min(3000,n * (n - 1) / 2)),任意兩點間只有一條邊,邊的長度都爲1,一開始的時候所有點都能通過某些路徑到達。要你求最多刪除幾條邊,能使s1到t1的距離不超過l1,s2到t2的距離不超過l2,如果情況不存在,輸出-1,否則輸出最多刪的邊的條數。


思路:看到點的個數比較少,可以先把所有i到j的最短路算出來,並用鄰接矩陣存起來,O(n^2)複雜度。接下來只要考慮兩種情況:1.s1到t1和s2到t2的路徑中沒有重合的邊,那麼只要單獨算兩條路徑的最短路即可。2.從兩條路徑的一個端點出發,路徑中會出現先沒有邊重合,後來有邊重合,最後又沒有邊重合的情況。對於第2種情況,只要枚舉重合路徑的兩個端點,然後不斷更新答案就可以了。

另外需要特別注意的是,兩個路徑可能是從s1,s2出發(t1,t2也一樣。。。)或者是s1,t2出發(s2,t1也一樣。。。),這是兩種不同的情況要分開考慮,所以還要swap(s1,t1)才能AC。。。。


#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn = 3005;
int dis[maxn][maxn];
vector<int> vec[maxn];

int n,m;
void bfs(int x)
{
	queue<int> que;
	dis[x][x] = 0;
	que.push(x);
	while(!que.empty())
	{
		int temp = que.front();
		que.pop();
		for(int i = 0;i < vec[temp].size();i++)
		{
			int v = vec[temp][i];
			if(dis[x][v] == -1)
			{
				dis[x][v] = dis[x][temp] + 1;
				que.push(v);
			}
		}
	}
}
int s[2],t[2],l[2];

void show()
{
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
			cout<<dis[i][j]<<" ";
		cout<<endl;
	}
}
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		mem(dis,-1);
		for(int i = 0;i <= n + 1;i++)vec[i].clear();
		for(int i = 0,a,b;i < m;i++)
		{
			scanf("%d%d",&a,&b);
			vec[a].push_back(b);
			vec[b].push_back(a);
		}
		for(int i = 1;i <= n;i++)
			bfs(i);
		scanf("%d%d%d%d%d%d",&s[0],&t[0],&l[0],&s[1],&t[1],&l[1]);
		int ans = 999999999;
		for(int oper = 0;oper < 2;oper++)
		{
			swap(s[1],t[1]);
			for(int i = 1;i <= n;i++)
				for(int j = 1;j <= n;j++)
				{
					int v[] = {dis[s[0]][i] + dis[i][j] + dis[j][t[0]],dis[s[1]][i] + dis[i][j] + dis[j][t[1]]};
					if(v[0] <= l[0] && v[1] <= l[1])
					{
						ans = min(ans,v[0] + v[1] - dis[i][j]);
					}
				}
		}
		if(dis[s[0]][t[0]] <= l[0] && dis[s[1]][t[1]] <= l[1])
			ans = min(ans,dis[s[0]][t[0]] + dis[s[1]][t[1]]);
		if(ans > m)
			ans = -1;
		else 
			ans = m - ans;
		printf("%d\n",ans);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章