Tokitsukaze and Rescue
题目大意
给一张完全图,每个边有边权。
问删掉k条边让从1到n的最短路最长,问这个最长的距离是多少?
边权随机,点的个数: 50
题解
做的时候,感觉到了这个题很暴力,但是没想到这么暴力。。
做的题少,主要不知道边权随机是干嘛用的。。
就是爆搜。。
跑一个最短路,枚举最短路上的边,然后删掉,继续跑最短路,继续枚举。
这样的话,复杂度是
这。。谁敢写啊。。
但是题解说由于边权随机,所以最短路径上的边的数量不是很多,这样可以过。。
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <map>
// #include <unordered_map>
#include <cmath>
#include <set>
#include <cstring>
#include <string>
// #include <unordered_set>
#include <bitset>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef unsigned long long ull;
typedef set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void wenjian(){
freopen("concatenation.in","r",stdin);freopen("concatenation.out","w",stdout);}
void tempwj(){
freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){
return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){
a %= mod;ll ans = 1;while(b){
if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{
bool operator()(const pii & a, const pii & b){
return a.second < b.second;}};
int lb(int x){
return x & -x;}
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 55+10;
int dis[maxn][maxn];
int per[maxn][maxn];
int vis[maxn];
int d[maxn];
int n;
void dj(int f)
{
for(int i = 1; i <= n; i ++ )
{
vis[i] = 0;
d[i] = dis[1][i];
per[f][i] = 1;
}
for (int i= 1; i < n; i ++ )
{
int minn = inf, k = -1;
for (int j = 1; j <= n; j ++ )
{
if(vis[j] == 0 && minn > d[j])
{
minn = d[j];
k = j;
}
}
if(k == -1)
break;
vis[k] = 1;
for(int j = 1; j <= n; j ++ )
{
if(vis[j] == 0 && d[j] > d[k] + dis[k][j])
{
d[j] = d[k] + dis[k][j];
per[f][j] = k;
}
}
}
}
int ans = 0;
void dfs(int num)
{
// printf("%d\n",num);
dj(num);
if(num == 0)
{
ans = max(ans,d[n]);
return;
}
// for(int i = 1; i <= n; i ++ )
// {
// int k = dis[per[num][i]][i];
// dis[per[num][i]][i] = inf;
// dis[i][per[num][i]] = inf;
// dfs(num - 1);
// dis[per[num][i]][i] = dis[i][per[num][i]] = k;
// }
int temp;
for(int i = n; i != 1; i = temp)
{
temp = per[num][i];
// printf("%d\n", temp);
int k = dis[temp][i];
dis[temp][i] = dis[i][temp] = inf;
dfs(num - 1);
dis[temp][i] = dis[i][temp] = k;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T -- )
{
ans =0 ;
int m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)for(int j=1; j<=n; j++)dis[i][j]=i==j?0:inf;
for (int i= 1; i<= n * (n - 1) / 2; i ++ )
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
dis[x][y] = dis[y][x] = v;
}
dfs(m);
cout<<ans<<endl;
}
}
这道题。。。 做的时候想了很多,,什么分层图,网络流,二分之类的都想了,但是感觉都不是,于是就没完了。。。没想到这么暴力,一定要会算时间复杂度。好重要呀。