“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛
Posted heyuhhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛相关的知识,希望对你有一定的参考价值。
A. 组队比赛
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 12:00:50
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int a[4];
void run() {
for(int i = 0; i < 4; i++) cin >> a[i];
int ans = min(abs(a[0] + a[3] - a[1] - a[2]), abs(a[0] + a[1] - a[2] - a[3]));
ans = min(ans, abs(a[0] + a[2] - a[1] - a[3]));
cout << ans << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
B. 每日一报
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 12:10:50
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
struct p {
string day, num;
double t;
bool operator < (const p &A) const {
if(day != A.day) return day > A.day;
if(t != A.t) return t > A.t;
return num < A.num;
}
}a[N];
void run() {
int n; cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].day >> a[i].num >> a[i].t;
}
sort(a + 1, a + n + 1);
vector <p> ans;
for(int i = 1; i <= n; i++) if(a[i].t >= 38.0) {
ans.push_back(a[i]);
}
cout << sz(ans) << ‘
‘;
for(auto it : ans) {
cout << it.day << ‘ ‘ << it.num << ‘ ‘ << it.t << ‘
‘;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(1);
run();
return 0;
}
C. 最长非公共子序列
贪心。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 12:07:36
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
string s, t; cin >> s >> t;
if(s == t) {
cout << -1 << ‘
‘;
return;
}
int n = s.length(), m = t.length();
cout << max(n, m) << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
D. 最大字符集
00
010
0110
...
这样构造即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 12:42:40
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <string> ans;
string now = "";
for(int i = 1; i <= n; i++) now += "1";
int fir = 0, last = now.length() - 1;
for(int i = n, op = (n & 1 ? 0 : 1); i >= 1; i--, op ^= 1) {
ans.push_back(now);
int f = 0;
now.pop_back(), --last;
if(op) {
if(last < fir) f = 1;
else now[last] = ‘0‘;
} else {
if(fir > last) f = 1;
else now[fir++] = ‘0‘;
}
if(f) break;
}
cout << sz(ans) << ‘
‘;
reverse(all(ans));
for(auto it : ans) cout << it << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
E. 美味的序列
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 12:04:51
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int d = 0;
ll ans = 0;
for(int i = 0; i < n; i++) {
ans += a[i] - d;
++d;
}
cout << ans << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
F. 日期小助手
枚举。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 14:38:04
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
const int date[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int calc(int y, int m, int d)
{
if(m==1||m==2)
{
m+=12;
y--;
}
int Week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
return Week + 1;
}
void run() {
int y, m, d; cin >> y >> m >> d;
int w = calc(y, m, d);
int cnt1 = 0, cnt2 = 0;
if(m == 5) {
int now = calc(y, m, 1);
for(int i = 1; i <= d; i++) {
if(now == 7) ++cnt1;
now = (now % 7) + 1;
}
}
if(m == 6) {
int now = calc(y, m, 1);
for(int i = 1; i <= d; i++) {
if(now == 7) ++cnt2;
now = (now % 7) + 1;
}
}
while(1) {
w = w % 7 + 1;
if(++d > date[m] + ((m == 2) && ((y % 400 == 0) || (y % 100 != 0 && y % 4 == 0)))) d = 1, ++m;
if(m > 12) m = 1, ++y;
if(m == 5 && w == 7 && ++cnt1 == 2) {
cout << "Mother‘s Day: May " << d;
if(d == 1 || d == 21 || d == 31) cout << "st, ";
else if(d == 2 || d == 22 || d == 32) cout << "nd, ";
else if(d == 3 || d == 23 || d == 33) cout << "rd, ";
else cout << "th, ";
cout << y << ‘
‘;
return;
}
if(m == 6 && w == 7 && ++cnt2 == 3) {
cout << "Father‘s Day: June " << d;
if(d == 1 || d == 21 || d == 31) cout << "st, ";
else if(d == 2 || d == 22 || d == 32) cout << "nd, ";
else if(d == 3 || d == 23 || d == 33) cout << "rd, ";
else cout << "th, ";
cout << y << ‘
‘;
return;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
G. 血压游戏
题意:
给出一颗树,每个结点上有(a_i)只松鼠。
若一个结点上有多余(1)只松鼠,它们会打架,那么就会阵亡一只,每个结点在同一时刻进行该操作。
然后所有松鼠会往上跳一个结点,继续进行打架操作。
若有松鼠位于根的位置,那么往上面跳就会到安全地带,它们再也不用打架了。
计算最终多少松鼠回到地面。
思路:
注意到所有会打架的松鼠一开始都位于相同的深度,那么根据这一点我们将所有深度相同的松鼠单独拿出来计算。
显然对于一层的松鼠往上跳的过程我们可以直接自下往上(dp)计算。
但直接这样算复杂度是(O(n^2))的,显然时空不能承受。
其实我们每一层计算的时候,有很多没有用的点,那些点我们完全没有必要在(dp)时加进来。我们只需要若干个有用的点就行。这就涉及到“虚树”。我们对每一层的结点拿出来构造虚树,假设一层结点为(k)个,那么虚树结点不超过(2k)个。然后直接跑(dp)。
这样时间复杂度即为(O(nlogn)),瓶颈在于求(lca)。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/19 17:26:40
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
int in[N], out[N], T;
int f[N][20], deep[N];
vector <int> G[N];
void dfs(int u, int fa) {
in[u] = ++T;
deep[u] = deep[fa] + 1;
f[u][0] = fa;
for(int i = 1; i < 20; i++) {
f[u][i] = f[f[u][i - 1]][i - 1];
}
for(auto v : G[u]) if(v != fa) {
dfs(v, u);
}
out[u] = T;
}
int LCA(int x, int y) {
if(deep[x] < deep[y]) swap(x, y);
for(int i = 19; i >= 0; i--) {
if(deep[f[x][i]] >= deep[y]) x = f[x][i];
}
if(x == y) return x;
for(int i = 19; i >= 0; i--) {
if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
}
return f[x][0];
}
int dis(int x, int y) {
int z = LCA(x, y);
return deep[x] + deep[y] - 2 * deep[z];
}
int V[N << 1], tot;
vector <int> vt[N];
void clear() {
for(int i = 1; i <= tot; i++) vt[V[i]].clear();
}
int buildVT(vector<int>& nodes) {
static int st[N], top;
auto cmp = [&](int x, int y) {
return in[x] < in[y];
};
auto chk = [&](int x, int y) {
return in[y] >= in[x] && in[y] <= out[x];
};
tot = 0;
for(auto it : nodes) V[++tot] = it;
sort(V + 1, V + 1 + tot, cmp);
for(int i = 1, tmp = tot; i < tmp; i++) V[++tot] = LCA(V[i], V[i + 1]);
sort(V + 1, V + 1 + tot, cmp);
tot = unique(V + 1, V + 1 + tot) - V - 1;
st[top = 1] = V[1];
for(int i = 2; i <= tot; i++) {
while(top > 1 && !chk(st[top], V[i])) --top;
vt[st[top]].push_back(V[i]);
st[++top] = V[i];
}
return V[1];
}
int n, s;
int a[N];
vector <int> D[N];
ll dp[N];
void DP(int u) {
if(!sz(vt[u])) dp[u] = a[u];
else dp[u] = 0;
for(auto v : vt[u]) {
DP(v);
if(dp[v]) dp[u] += max(1ll, dp[v] - (deep[v] - deep[u]));
}
}
void run() {
cin >> n >> s;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(s, 0);
for(int i = 1; i <= n; i++) {
D[deep[i]].push_back(i);
}
ll ans = 0;
for(int i = 1; i <= n; i++) if(sz(D[i])) {
int rt = buildVT(D[i]);
DP(rt);
if(dp[rt]) ans += max(1ll, dp[rt] - (deep[rt] - deep[s]) - 1);
clear();
}
cout << ans << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
H. 纸牌游戏
题意:
现有(n)张数字牌,每张都包含(0)~(9)其中一个阿拉伯数字。
现在要从中选出(k)张,组成一个能被(3)整除的非负整数,并要求组成的数最大。
思路:
容易证明,我们将所有的数按照模(3)进行分类,然后要选出若干个数,每类数最多选(2)张即可构成所有情况。
那么直接暴力就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 19:51:22
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
char s[N];
int cnt[10], ans[10];
bool dfs(int x, int k, int m) {
if(x == -1) {
return k == 0 && m == 0;
}
int r = min(k, cnt[x]);
if(x == 0) {
int f = 1;
for(int i = 1; i < 10; i++) {
if(ans[i] > 0) f = 0;
}
if(f) r = min(cnt[x], 1);
}
int l = max(0, r - 2);
for(int i = r; i >= l; i--) {
ans[x] = i;
if(dfs(x - 1, k - i, (m + i * x) % 3)) return true;
}
return false;
}
void run() {
int n, k;
cin >> (s + 1) >> k;
n = strlen(s + 1);
for(int i = 0; i < 10; i++) cnt[i] = ans[i] = 0;
for(int i = 1; i <= n; i++) {
++cnt[s[i] - ‘0‘];
}
if(!dfs(9, k, 0)) cout << -1 << ‘
‘;
else {
for(int i = 9; i >= 0; i--) {
for(int j = 1; j <= ans[i]; j++) cout << i;
}
cout << ‘
‘;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
I. 古老的打字机
题意:
现有一个打字机,每次会随机打一个英文字母或者一个退格键。
现在随机敲打(m,mleq 1000)次,会得到字符串(t)。
给定(n,nleq 1000)个字符串,每个字符串价值为(v_i)。
定义最后串(t)的价值为每个字符串出现的次数乘以对应价值。
求得到字符串价值的期望。
思路:
根据期望线性性质,我们可以直接对每个串进行考虑,现在问题就转化为只有一个字符串时的期望价值。
我们还可以继续将问题细分,求出最终串长度为(s)的期望,那么我们可以用(dp)求出(dp[m][s])。
再次利用期望线性性,求出串以每个位置为开头的期望,因为题目最后要乘以(27^m),所以我们相当于算分子部分,即每个串出现的次数。
出现的次数即为(所有可能的位置cdot 在该位置出现的概率)。
那么就没了。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/19 9:23:38
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e3 + 5, MOD = 1e9 + 7;
int qpow(ll a, ll b) {
ll res = 1;
while(b) {
if(b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
void add(int &x, int y) {
x += y;
if(x >= MOD) x -= MOD;
}
int dp[N][N], ipow[N];
string str[N];
int a[N];
void run() {
int n, m; cin >> n >> m;
ipow[0] = 1, ipow[1] = qpow(26, MOD - 2);
for(int i = 1; i <= m; i++) ipow[i] = 1ll * ipow[i - 1] * ipow[1] % MOD;
dp[0][0] = 1;
for(int i = 0; i < m; i++) {
for(int j = 0; j < N; j++) if(dp[i][j]) {
add(dp[i + 1][max(j - 1, 0)], dp[i][j]);
add(dp[i + 1][j + 1], 1ll * dp[i][j] * 26 % MOD);
}
}
int ans = 0;
for(int i = 1; i <= n; i++) cin >> str[i] >> a[i];
for(int i = 1; i <= m; i++) {
int s = 0;
for(int j = 1; j <= n; j++) {
int len = str[j].length();
if(i >= len) {
add(s, 1ll * (i - len + 1) * a[j] % MOD * ipow[len] % MOD);
}
}
add(ans, 1ll * s * dp[m][i] % MOD);
}
cout << ans << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
L. 动物森友会
二分天数,然后网络流进行check即可。
只需要判断最大流是否大于(sum c_i)。
Code
/*
* Author: heyuhhh
* Created Time: 2020/4/18 15:28:41
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ‘ ‘; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ‘ ‘; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2000 + 5, M = 10000 + 5;
int n, e;
int c[N];
vector <vector<int>> a(8);
template <class T>
struct Dinic{
struct Edge{
int v, next;
T flow;
Edge(){}
Edge(int v, int next, T flow) : v(v), next(next), flow(flow) {}
}e[M << 1];
int head[N], tot;
int dep[N];
void init() {
memset(head, -1, sizeof(head)); tot = 0;
}
void adde(int u, int v, T w, T rw = 0) {
e[tot] = Edge(v, head[u], w);
head[u] = tot++;
e[tot] = Edge(u, head[v], rw);
head[v] = tot++;
}
bool BFS(int _S, int _T) {
memset(dep, 0, sizeof(dep));
queue <int> q; q.push(_S); dep[_S] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(!dep[v] && e[i].flow > 0) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[_T] != 0;
}
T dfs(int _S, int _T, T a) {
T flow = 0, f;
if(_S == _T || a == 0) return a;
for(int i = head[_S]; ~i; i = e[i].next) {
int v = e[i].v;
if(dep[v] != dep[_S] + 1) continue;
f = dfs(v, _T, min(a, e[i].flow));
if(f) {
e[i].flow -= f;
e[i ^ 1].flow += f;
flow += f;
a -= f;
if(a == 0) break;
}
}
if(!flow) dep[_S] = -1;
return flow;
}
T dinic(int _S, int _T) {
T max_flow = 0;
while(BFS(_S, _T)) max_flow += dfs(_S, _T, INF);
return max_flow;
}
};
Dinic <int> solver;
bool chk(int x) {
solver.init();
for(int i = 1; i <= 7; i++) {
int t = (x - 1) / 7, r = (x - 1) % 7 + 1;
ll now = 1ll * (t + (i <= r)) * e;
if(now > (ll)INF) now = INF;
solver.adde(0, i, now);
}
for(int i = 1; i <= 7; i++) {
for(auto j : a[i]) {
solver.adde(i, j + 7, INF);
}
}
int T = 2000, sum = 0;
for(int i = 1; i <= n; i++) {
solver.adde(i + 7, T, c[i]);
sum += c[i];
}
return solver.dinic(0, T) >= sum;
}
void run() {
cin >> n >> e;
for(int i = 1; i <= n; i++) {
cin >> c[i]; int x; cin >> x;
for(int j = 1; j <= x; j++) {
int t; cin >> t;
a[t].push_back(i);
}
}
int l = 1, r = INF, mid;
while(l < r) {
mid = (l + r) >> 1;
if(chk(mid)) r = mid;
else l = mid + 1;
}
cout << l << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
以上是关于“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛的主要内容,如果未能解决你的问题,请参考以下文章
“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛
“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛
“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛(C~D)
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 I.丢史蒂芬妮