2017 ICPC 乌鲁木齐
H:题目看错 背锅
#include <bits/stdc++.h> #include <vector> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-9; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e4 + 10; const int maxm = 300; vector<pair<int, int> > p[10005]; int visit[maxn]; int ans[maxn]; int anser = 0; void dfs(int cur) { int len = p[cur].size(); if (len == 0) { ans[cur] = 0; } for (int i = 0; i < len; i++) { int to = p[cur][i].first; int lenth = p[cur][i].second; if (ans[to] != -1) { ans[cur] = max(ans[cur], ans[to] + lenth); } else { dfs(to); ans[cur] = max(ans[cur], ans[to] + lenth); } } } int main() { int t; cin >> t; while (t--) { anser = 0; mem(visit, 0); mem(ans, -1); int n, m; int from, to, lenth; cin >> n >> m; for (int i = 1; i <= m; i++) { scanf("%d %d %d", &from, &to, &lenth); visit[to] = 1; p[from].pb(make_pair(to, lenth)); } for (int i = 1; i <= n; i++) { if (visit[i] == 0) { //cout<<i<<endl; dfs(i); anser = max(anser, ans[i]); } } cout << anser << endl; for (int i = 1; i <= n; i++) { p[i].clear(); } } }
G:每个test 后面没换行 背锅
#include <bits/stdc++.h> #include <vector> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-9; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e5 + 10; const int maxm = 300; int n, m, i, num[100001], tree[200001], l, r; char s[maxn], t[maxn]; int slen, tlen, lencha; string ch, ch1; int lowbit(int x) { return x & (-x); } void update(int x, int p) { while (x <= n) { tree[x] += p; x += lowbit(x); } return; } int sum(int k) { int ans = 0; while (k > 0) { ans += tree[k]; k -= lowbit(k); } return ans; } int ask(int l, int r) { return sum(r) - sum(l - 1); } int main() { /*cin>>n>>m; for(i=1;i<=n;i++) { cin>>num[i]; update(i,num[i]); } for(i=1;i<=m;i++) { cin>>l>>r; cout<<ask(l,r)<<endl; }*/ int time; cin >> time; while (time--) { //mem(num, 0); mem(tree, 0); int now; scanf("%d",&m); scanf("%s", s + 1); scanf("%s", t); slen = strlen(s + 1); tlen = strlen(t); //cout<<slen<<" "<<tlen<<endl; lencha = slen - tlen + 1; n = slen; for (int i = 1; i <= lencha; i++) { for (int j = 0; j <= tlen; j++) { if (j == tlen) { num[i] = 1; update(i, num[i]); break; } if (s[i + j] != t[j]) { num[i] = 0; update(i, num[i]); break; } } } /*for (int i = 1; i <= slen; i++) { cout << num[i] << " "; } cout << endl;*/ for (int i = 1; i <= m; i++) { cin >> ch; if (ch[0] == 'Q') { scanf("%d %d", &l, &r); printf("%d\n", ask(l, r - tlen + 1)); } else if (ch[0] == 'C') { int flag = 0; scanf("%d", &now); cin >> ch1; if (s[now] != ch1[0]) { flag = 1; } s[now] = ch1[0]; int from = max(1, now - tlen + 1); int to = min(lencha, now); if (flag) { for (int j = from; j <= to; j++) { if (num[j] == 1) { num[j] = 0; update(j, -1); } else { for (int k = 0; k <= tlen; k++) { if (k == tlen) { num[j] = 1; update(j, 1); break; } if (s[j + k] != t[k]) { break; } } } } } /*for (int i = 1; i <= slen; i++) { cout << num[i] << " "; } cout << endl;*/ } } puts(""); } return 0; }
J!!!!!!:最小费用最大流
每个城市拆成出点和入点,源点连西安和大连,汇点连上海,相当于求从西安到上海和从大连到上海最小距离之和,每个城市入点和出点之间连一条容量为1的边,但是注意,上海的容量必须是2,再根据给出的边,分别连接出点入点,存入相应花费,那么问题就可以转化成最小费用最大流了,如果流量不为2输出-1,否则输出最小花费。
#include<stdio.h> #include<algorithm> #include<string.h> #include<map> #include<queue> #include<string> using namespace std; #define ll long long const ll maxm = 10005; const ll INF = 1e18 + 7; struct node { ll u, v, flow, cost, next; }edge[maxm * 10]; map<string, ll>p; ll cnt, s, t, n, m, sum, FLOW; ll head[maxm * 10], dis[maxm * 10], pre[maxm * 10]; char a[maxm], b[maxm]; void init() { p.clear(); cnt = 0, s = 0, t = n * 5 + 1, sum = 0, FLOW = 0; memset(head, -1, sizeof(head)); } void add(ll u, ll v, ll flow, ll cost) { edge[cnt].u = u, edge[cnt].v = v; edge[cnt].flow = flow, edge[cnt].cost = cost; edge[cnt].next = head[u], head[u] = cnt++; edge[cnt].u = v, edge[cnt].v = u; edge[cnt].flow = 0, edge[cnt].cost = -cost; edge[cnt].next = head[v], head[v] = cnt++; } ll bfs() { queue<ll>q; for (ll i = 0;i <= t;i++) dis[i] = INF; memset(pre, -1, sizeof(pre)); dis[s] = 0, q.push(s); ll rev = 0; while (!q.empty()) { ll u = q.front();q.pop(); for (ll i = head[u];i != -1;i = edge[i].next) { ll v = edge[i].v; if (dis[v] > dis[u] + edge[i].cost&&edge[i].flow) { dis[v] = dis[u] + edge[i].cost; pre[v] = i, q.push(v); } } } if (dis[t] == INF) return 0; return 1; } ll MCMF() { ll ans = 0, minflow; while (bfs()) { minflow = INF; for (ll i = pre[t];i != -1;i = pre[edge[i].u]) minflow = min(minflow, edge[i].flow); for (ll i = pre[t];i != -1;i = pre[edge[i].u]) edge[i].flow -= minflow, edge[i ^ 1].flow += minflow; ans += dis[t] * minflow; FLOW += minflow; } return ans; } int main() { ll i, j, k, T, c; scanf("%lld", &T); while (T--) { scanf("%lld", &n); init(); ll nn = n * 2; for (i = 1;i <= n;i++) { scanf("%s%s%lld", a, b, &c); if (p[a] == 0) { p[a] = ++sum, k = 1; if (strcmp(a, "Shanghai") == 0) k = 2; add(p[a], p[a] + nn, k, 0); } if (p[b] == 0) { p[b] = ++sum, k = 1; if (strcmp(b, "Shanghai") == 0) k = 2; add(p[b], p[b] + nn, k, 0); } ll u = p[a], v = p[b]; add(u + nn, v, INF, c); add(v + nn, u, INF, c); } ll u = p["Dalian"]; add(s, u, 1, 0); u = p["Xian"]; add(s, u, 1, 0); u = p["Shanghai"]; add(u + nn, t, 2, 0); ll ans = MCMF(); if (FLOW == 2) printf("%lld\n", ans); else printf("-1\n"); } return 0; }