C
题意:
一个地区有N个编号为1到N的城镇,以及M条编号为1到M的道路。
第i条道路以长度Ci双向连接城镇Ai和Bi。
在不经过同一个城镇两次的情况下,从一个城镇出发到达另一个城镇时,找到可能的道路总长度的最大值。
dfs
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, m, res;
int d[N][N];
vector<int>v[N];
bool st[N];
int dfs(int x, int dist)
{
st[x] = true;
bool f = 1;
for(auto i : v[x])
{
if(st[i]) continue;
f = 0;
dfs(i, dist + d[x][i]);
}
if(f) res = max(res, dist);
st[x] = false;//恢复现场
return res;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[a][b] = d[b][a] = c;
v[a].push_back(b);
v[b].push_back(a);
}
for(int i = 1; i <= n; i ++)
{
memset(st, false, sizeof st);
dfs(i, 0);
}
cout << res << endl;
return 0;
}
D
题意:
选民投票,有 N个区域,保证每个区域都不会有同票拍的情况。 i 区有 Xi+Yi 名选民,其中 Xi名是高桥, Yi名是青木。得票高的人会在这个区域赢得 Zi 票。问如果高木想要赢得这场投票,最少需要贿赂多少人投他。
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int>pii;
const int inf = 1e18;
int n, z, t, aoki;
vector<pii>v;
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
int a, b, c;
cin >> a >> b >> c;
z += c;
if(a > b) t += c;
else
{
aoki += c;
int cost = (a + b + 1) / 2 - a; //需要贿赂的人数
v.push_back({cost, c}); //需要贿赂的人数 和 可以获得的席位
}
}
int ans = inf;
vector<int>dp(300010, inf);
dp[0] = 0; //状态: 获得这么多的席位 需要贿赂的人数
for(auto x : v)
{
int cost = x.first;
int win = x.second;
for(int j = 100000; j >= win; j --)
dp[j] = min(dp[j], dp[j - win] + cost);
}
if(t >= (z + 1)/2)
{
cout << 0 << endl;
return 0;
}
for(int j = (z + 1)/2 - t; j <= 100000; j ++)
ans = min(ans, dp[j]);
cout << ans << endl;
return 0;
}