啦啦啦啦啦
嚕嚕嚕嚕嚕
嘟嘟嘟嘟嘟
野野野野野
這題出自 Codeforces Prefix Sum Primes
詳細的討論在一開始的累計到達
#include <bits/stdc++.h>
using namespace std;
int n, one, two;
int main() {
cin >> n;
one = two = 0;
int tmp;
for(int i = 0; i < n; i++) {
cin >> tmp;
if(tmp == 1) one++;
else two++;
}
if(two >= 1 && one >= 1) {
cout << 2 << " " << 1;
for(int i = 0; i < two-1; i++) cout << " " << 2;
for(int i = 0; i < one-1; i++) cout << " " << 1;
}
else if(one >= 1) {
if(one >= 3) {
for(int i = 0; i < 3; i++) cout << (i == 0? "": " ") << 1;
for(int i = 0; i < two; i++) cout << " " << 2;
for(int i = 0; i < one-3; i++) cout << " " << 1;
}
else {
cout << 1;
for(int i = 0; i < two; i++) cout << " " << 2;
for(int i = 0; i < one-1; i++) cout << " " << 1;
}
}
else {
for(int i = 0; i < two; i++) cout << (i==0?"": " ") << 2;
}
cout << endl;
return 0;
}
因為可以隨便亂排,為了保證一定可以達到題目中的要求,先對其中一項排序,再對另一項做 LIS,另外,由於
#include <bits/stdc++.h>
using namespace std;
struct node {
int wei;
int money;
};
bool cmp(node& a, node& b) {
if (a.wei == b.wei) {
return a.money < b.money;
}
return a.wei < b.wei;
}
bool cmp2(node a, node b) { return a.money > b.money; }
int main() {
int n, m, i, j, k;
vector<node> v;
n = 0;
int a, b;
while (cin >> a >> b) {
v.push_back({a, b});
n++;
}
sort(v.begin(), v.end(), cmp);
vector<node> LIS;
LIS.push_back(v[0]);
for (i = 1; i < n; i++) {
if (v[i].money < LIS.back().money && v[i].wei > LIS.back().wei) {
LIS.push_back(v[i]);
} else {
*lower_bound(LIS.begin(), LIS.end(), v[i], cmp2) = v[i];
}
}
cout << LIS.size() << endl;
return 0;
}
這題出自 UVa OJ 11770 Lighting Away
利用 SCC 當找出每組 SCC 時,判斷對於這個 SCC 是不是只有出沒有進。
team14, team6, team21, team11, team5 被 team22 hack成功!
🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣
#include <bits/stdc++.h>
#define vi vector<int>
#define pb push_back
using namespace std;
vector< vi > edge, invedge;
vi dfn, low;
stack<int> s;
vector<bool> instack;
int T, n, m, idx_dfn, ans;
void init() {
idx_dfn = 1, ans = 0;
edge.clear(); invedge.clear(); dfn.clear(); low.clear(); instack.clear();
edge.resize(n+1); invedge.resize(n+1); dfn.assign(n+1, -1); low.resize(n+1); instack.resize(n+1);
while(s.size()) s.pop();
}
void dfs(int u) {
dfn[u] = low[u] = idx_dfn++;
s.push(u);
instack[u] = 1;
for(int v: edge[u]) {
if(dfn[v] == -1) {
dfs(v);
low[u] = min(low[u], low[v]);
}
else if(instack[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]) {
queue<int> group;
set<int> who_in;
int tmp;
do {
tmp = s.top(); s.pop();
instack[tmp] = 0;
group.push(tmp);
for(int v: invedge[tmp]) who_in.insert(v);
}while(tmp != u);
while(group.size()) {
auto it = who_in.find(group.front());
if(it != who_in.end()) who_in.erase(it);
group.pop();
}
if(who_in.size() == 0) ans++; //nobody come in this group
}
}
int main() {
cin >> n >> m;
init();
for(int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
edge[u].pb(v);
invedge[v].pb(u);
}
for(int i = 1; i <= n; i++) if(dfn[i] == -1) dfs(i);
cout << ans << endl;
return 0;
}
題目要求輸出有多少種不同的贈品,而 sakura 擁有一些贈品,這個關係能構成下圖:
若同學(student) 擁有
根據交換規則 :
所以有關係圖:
也就是說,題目就是要求從 sakura 加入流,找出 output 的最大流量
#include<bits/stdc++.h>
using namespace std;
int const maxn = 60;
int const INF = maxn*50;
int n, m, R[maxn][maxn];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
int t, p;
scanf("%d", &t);
while(t--) scanf("%d", &p), R[i][n+p]++;
}
int out = n + m + 1; // out := output
for(int p = 1; p <= m; p++) R[n+p][out] = 1;
// 同學們與贈品的關係圖
for(int i = 2; i <= n; i++)
for(int p = 1; p <= m; p++) {
if(R[i][n+p] == 0) R[n+p][i] = 1;
else R[i][n+p]--;
}
// 找出最大流量
int s = 1, pre[maxn], flow[maxn], max_flow = 0; // s := sakura
bool vis[maxn];
while(1) {
memset(vis, false, sizeof(vis));
vis[s] = true;
memset(flow, 0, sizeof(flow));
flow[s] = INF;
queue<int> Q;
Q.push(s);
while(!Q.empty()) {
int u = Q.front(); Q.pop();
if(u == out) break;
for(int v = s; v <= out; v++) {
if(vis[v] || !R[u][v]) continue;
vis[v] = true;
flow[v] = min(flow[u], R[u][v]);
pre[v] = u;
Q.push(v);
}
}
if(flow[out] == 0) break;
max_flow += flow[out];
for(int v = out; v != s; v=pre[v]) {
int u = pre[v];
R[u][v] -= flow[out];
R[v][u] += flow[out];
}
}
printf("%d\n", max_flow);
return 0;
}
這裡 sakura 與同學們的編號為
而每種贈品編號為
output 的編號為
這題出自 UVa OJ 10731 Test
做一下 SCC 就過了
我不知道怎麼寫題解@~@
#include <bits/stdc++.h>
using namespace std;
#define maxN 100
bool first = 0, instack[maxN];
int n, num, idx, k, t, dfn[maxN], low[maxN];
map<string, int> id;
string x, y[5], name[maxN], temp[maxN];
vector<int> g[maxN];
stack<int> s;
set<string> ans;
void dfs(int u)
{
dfn[u] = low[u] = idx++;
s.push(u);
instack[u] = 1;
for(int v : g[u])
if(dfn[v] == -1) {
dfs(v);
low[u] = min(low[u], low[v]);
}
else if(instack[v])
low[u] = min(low[u], dfn[v]);
if(dfn[u] == low[u]) {
k = 0;
do {
t = s.top();
s.pop();
temp[k++] = name[t];
instack[t] = 0;
}while(t != u);
sort(temp, temp + k);
for(int i = 1; i < k; i++)
temp[0] += (" " + temp[i]);
ans.insert(temp[0]);
}
}
int main()
{
while(cin >> n && n) {
num = 0;
idx = 0;
id.clear();
ans.clear();
for(int i = 0; i < maxN; i++) {
g[i].clear();
dfn[i] = low[i] = -1;
instack[i] = 0;
}
while(s.size())
s.pop();
for(int i = 0; i < n; i++) {
for(int j = 0; j < 5; j++) {
cin >> y[j];
if(id.find(y[j]) == id.end()) {
name[num] = y[j];
id[y[j]] = num++;
}
}
cin >> x;
for(int j = 0; j < 5; j++)
if(y[j] != x)
g[id[x]].push_back(id[y[j]]);
}
for(int i = 0; i < num; i++)
if(dfn[i] == -1)
dfs(i);
if(first)
cout << '\n';
first = 1;
for(string i : ans)
cout << i << '\n';
}
return 0;
}