USACO 4.2 分析

來源:互聯網
上載者:User

 題目一: PROB Drainage Ditches

就是一道倮倮求最大流的題目

以下是 MAIGO 的PREFLOW 的演算法,差不多背下來了,但感覺應該去學一下DINIC演算法!

#include <iostream><br />#include <stdio.h><br />#include <string.h><br />using namespace std;<br />const int maxv = 201;<br />const int maxe = 401;<br />int first[maxv], v[maxv], aug[maxv], from[maxv];<br />int next[maxe], v1[maxe], v2[maxe], cap[maxe];<br />int n, m, e, i, x, y, t, ans;<br />int main() {<br />freopen("ditch.in", "r", stdin);<br />freopen("ditch.out", "w", stdout);<br />scanf("%d%d", &m, &n);<br />memset(first, -1, sizeof(first));<br />e = 0;<br />for (int i = 1; i <= m; i++) {<br />scanf("%d%d", &x, &y);<br />e++; v1[e] = x; v2[e] = y; scanf("%d", &cap[e]); next[e] = first[x]; first[x] = e;<br />e++; v1[e] = y; v2[e] = x; cap[e] = 0; next[e] = first[y]; first[y] = e;<br />}</p><p>ans = 0;<br />do {<br />memset(v, 0, sizeof(v));<br />memset(aug, 0, sizeof(aug));<br />x = 1; aug[1] = 1 << 30;<br />do {<br />v[x] = true;<br />for (int i = first[x]; i != -1; i = next[i]) {<br />if (cap[i] < aug[x]) t = cap[i]; else t = aug[x];<br />if (t > aug[v2[i]]) { aug[v2[i]] = t; from[v2[i]] = i; }<br />}<br />x = n;<br />for (int i = 1; i < n; i++)<br />if (!v[i] && aug[i] > aug[x]) x = i;//可能還可以或得更大的增廣路<br />} while (x < n);</p><p>if (!aug[n]) break;//找不到增廣路</p><p>ans += aug[n];<br />for (int i = from[n]; i != 0; i = from[v1[i]]) {<br />cap[i] -= aug[n];<br />if (i % 2) cap[i+1] += aug[n]; else cap[i-1] += aug[n];<br />}<br />} while (true);</p><p>printf("%d/n", ans);<br />return 0;<br />}

 

題目二:The Perfect Stall

演算法:倮倮的匈牙利

也基本上背下來了

#include <stdio.h><br />#include <string.h><br />const int maxn = 201;<br />int n, m, nn, mm, ans;<br />int p[maxn], h[maxn], f[maxn][maxn];<br />bool find(int x) {<br />for (int i = 1; i <= m; i++)<br />if (!h[i] && f[x][i]) {<br />h[i] = 1;<br />if (p[i] == -1 || find(p[i])) {<br />p[i] = x; return true;<br />}<br />}<br />return false;<br />}<br />int main(){<br />freopen("stall4.in", "r", stdin);<br />freopen("stall4.out", "w", stdout);<br />scanf("%d%d", &n, &m);<br />for (int i = 1; i <= n; i++) {<br />scanf("%d", &nn);<br />for (int j = 1; j <= nn; j++) {<br />scanf("%d", &mm);<br />f[i][mm] = 1;<br />}<br />}<br />memset(p,-1,sizeof(p));<br />ans = 0;<br />for (int i = 1; i <= n; i++) {<br />memset(h,0,sizeof(h));<br />if (find(i)) ans++;<br />}<br />printf("%d/n", ans);<br />return 0;<br />}

 

題目三:Job Processing

演算法:貪心

還不是很懂,以下是MAIGO的方法

#include <stdio.h><br />#include <string.h><br />const int maxn = 1000, maxm = 30;<br />int ta[maxm], tb[maxm], ja[maxm], jb[maxm];<br />int sa[maxn], sb[maxn];<br />int n, m1, m2, i, j, t;<br />int main(){<br />freopen("job.in", "r", stdin);<br />freopen("job.out", "w", stdout);<br />scanf("%d%d%d", &n, &m1, &m2);<br />for (i = 0; i < m1; i++) { scanf("%d", &ta[i]); ja[i] = ta[i]; }<br />for (i = 0; i < m2; i++) { scanf("%d", &tb[i]); jb[i] = tb[i]; }<br />for (i = 0; i < n; i++) {<br />t = 0; for (j = 1; j < m1; j++) if (ja[j] < ja[t]) t = j; sa[i] = ja[t]; ja[t] += ta[t];<br />t = 0; for (j = 1; j < m2; j++) if (jb[j] < jb[t]) t = j; sb[n-i-1] = jb[t]; jb[t] += tb[t];<br />}<br />t = 0;<br />for (i = 1; i < n; i++) if (sa[i]+sb[i] > sa[t]+sb[t]) t = i;<br />printf("%d %d/n", sa[n-1], sa[t]+sb[t]);<br />return 0;<br />}

 

題目四:Cowcycles

** Description: 給定前後齒輪可以選取的數值,從前齒輪和後齒輪中選取F,R個,
    求在滿足3x(最大轉速/最小轉速>=3)條件下,按照運算規則方差最小的組合?
** Algorithm:   DFS
** Analysis: 自己的搜尋功底真得很欠缺啊。。。
    1.分別枚舉前後齒輪的情況;
    2.根據公式 x = (fmax/rmin)/(fmin/rmax) >= 3,知
     3*rmin*fmin <= fmax*rmax
     剪枝1:枚舉第一個fmin,rmin的時候,如果不滿足這個條件,直接退出;(根據遞增性)
     剪枝2:枚舉完fmax,rmax判斷;
     剪枝3:枚舉的邊界 finish 的控制
     剪枝4:網上說對於比較少的數,不如用插入排序來得快。

#include <iostream><br />#include <algorithm><br />#include <string.h><br />#include <stdio.h><br />using namespace std;<br />const int maxn = 20;<br />int f, r, f1, f2, r1, r2;<br />int gear[maxn], g[maxn];<br />double x[51];<br />double best = 1 << 30;<br />void update() {<br />if (3*gear[f+1]*gear[1] > gear[f]*gear[f+r]) return;//CUT 2<br />int i, j, tot = 0;<br />for (i = 1; i <= f; i++)<br />for (j = 1; j <= r; j++)<br />x[tot++] = 1.0*gear[i]/gear[f+j];<br />sort(x, x+tot);</p><p>double ave = 0, dif = 0;<br />tot--;<br />for (i = 0; i < tot; i++) {<br />x[i] = x[i+1]-x[i];<br />ave += x[i];<br />}<br />ave /= tot;</p><p>for (i = 0; i < tot; i++)<br />dif += (ave-x[i]) * (ave-x[i]);</p><p>if (dif < best) {<br />best = dif;<br />memcpy(g, gear, (f+r+1)*sizeof(int));<br />}<br />}<br />void dfs(int l) {<br />int start, finish;<br />if (l == 1) start = f1; else if (l == f+1) start = r1; else start = gear[l-1]+1;<br />if (l <= f) finish = f2-f+l; else finish = r2-(r+f)+l;<br />for (int i = start; i <= finish; i++) {<br />//3*f1*r1 <= r2*f2 should be guaranteed<br />if (l == 1 && 3*r1*i > f2*r2) return;//CUT 1<br />if (l == f+1 && 3*i*gear[1] > gear[f]*r2) return;//CUT 1<br />gear[l] = i;<br />if (l != f || 3*r1*gear[1] <= gear[l]*r2)//CUT 2<br />if (l == f+r) update(); else dfs(l+1);<br />}<br />}<br />int main(){<br />freopen("cowcycle.in", "r", stdin);<br />freopen("cowcycle.out", "w", stdout);<br />scanf("%d%d", &f, &r);<br />scanf("%d%d%d%d", &f1, &f2, &r1, &r2);<br />dfs(1);<br />for (int i = 1; i < f; i++) printf("%d ", g[i]);<br />printf("%d/n", g[f]);<br />for (int i = 1; i < r; i++) printf("%d ", g[f+i]);<br />printf("%d/n", g[f+r]);<br />return 0;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.