“Wishare杯”南郵第八屆大學生程式設計競賽之網路預賽 題解報告
阿新 • • 發佈:2019-01-26
對於第二組樣例
第一個人可以以(1,1) -> (2,1) -> (2, 2) -> (3,2) -> (3,3)的順序說服5個妹子
第二個人的順序可以是(1, 1) -> (2, 1) -> (3, 1),因為(1,1) (2,1)位置的妹子已經被說服了,他這一輪只說服了一個妹子。
兩輪下來所有妹子都被說服,因此總顏值就是她們的顏值和為21
題目分析:最大費用最大流,超源連起點,終點連超匯,費用為0,容量為k,有權值的點拆點鍵圖,拆完點兩條邊一條費用為權值,容量為1保證取值,另一條費用為0,容量無窮大保證可重複走,然後跑個費用流~
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define ll long long using namespace std; int const INF = 0x3fffffff; int const MAX = 26 * 26; int n, k; int head[MAX << 2], cnt; int pre[MAX << 2], vis[MAX << 2]; int src, sk; ll ans, a[30][30], dis[MAX << 2]; struct EGDE { int to, nxt, cap; ll cost; }e[MAX << 3]; void Init() { ans = 0; src = 0; sk = 2 * n * n + 1; cnt = 0; memset(head, -1, sizeof(head)); } void Add(int u, int v, int cap, ll cost) { e[cnt].to = v; e[cnt].cap = cap; e[cnt].cost = cost; e[cnt].nxt = head[u]; head[u] = cnt ++; e[cnt].to = u; e[cnt].cap = 0; e[cnt].cost = -cost; e[cnt].nxt = head[v]; head[v] = cnt ++; } void Build_graph() { Add(src, 1, k, 0); for(int i = 1; i <= n; i++) { for(int j = 1; j <= i; j++) { Add((i - 1) * n + j, n * n + (i - 1) * n + j, 1, a[i][j]); Add((i - 1) * n + j, n * n + (i - 1) * n + j, INF, 0); if(j < n) Add(n * n + (i - 1) * n + j, (i - 1) * n + j + 1, INF, 0); if(i < n) Add(n * n + (i - 1) * n + j, i * n + j, INF, 0); } } Add(2 * n * n, sk, k, 0); } bool SPFA() { memset(vis, false, sizeof(vis)); memset(dis, -1, sizeof(dis)); memset(pre, -1, sizeof(pre)); queue <int> q; q.push(src); vis[src] = true; dis[src] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i != -1; i = e[i].nxt) { int v = e[i].to; int cap = e[i].cap; ll cost = e[i].cost; if(cap > 0 && dis[v] < dis[u] + cost) { dis[v] = dis[u] + cost; pre[v] = i; if(!vis[v]) { vis[v] = true; q.push(v); } } } } return dis[sk] != -1; } void Augment() { int mi = INF; while(SPFA()) { for(int i = sk; i != src; i = e[pre[i] ^ 1].to) mi = min(mi, e[pre[i]].cap); for(int i = sk; i != src; i = e[pre[i] ^ 1].to) { ans += (ll)mi * e[pre[i]].cost; e[pre[i]].cap -= mi; e[pre[i] ^ 1].cap += mi; } } } int main() { int T; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &k); for(int i = 1; i <= n; i++) for(int j = 1; j <= i; j++) scanf("%I64d", &a[i][j]); Init(); Build_graph(); Augment(); printf("%I64d\n", ans); } }
文科生or理科生
時間限制(普通/Java):1000MS/3000MS 執行記憶體限制:32768KByte#include <cstdio> #include <cmath> int main() { int T; scanf("%d", &T); while(T --) { double n; scanf("%lf", &n); if(n >= 20) printf("%.6f\n", (n + 3.0) / sqrt(n)); else { double f = 1.0; for(int i = 2; i <= n + 1; i++) f = f * i * 1.0; printf("%.6f\n", (n + 3.0 - 3.0 / f) / sqrt(n)); } } }