编程之美初赛第二场
Problem A
一边输入边一边维护残留网络,然后跑ISAP。小数据过了,大数据TLE。据说可以BFS预处理 层次网络。可以过。
View Code
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<iostream> using namespace std; const int inf = 10000000; const int MAXN = 500; #define MIN(a,b) (a)<(b)?(a):(b) #define MAX(a,b) (a)>(b)?(a):(b) int k, c, m, s, t, n, N; int mp[MAXN][MAXN]; int head[MAXN], idx, vh[MAXN], h[MAXN]; struct node{ int v, f, nxt; }edge[MAXN*MAXN]; void AddEdge( int u, int v, int f ) { edge[idx].v = v; edge[idx].f = f; edge[idx].nxt = head[u]; head[u] = idx++; edge[idx].v = u; edge[idx].f = 0; edge[idx].nxt = head[v]; head[v] = idx++; } int DFS(int u,int flow ) { if( u == t ) return flow; int tmp = h[u]+1, remain = flow; for(int i = head[u]; ~i; i = edge[i].nxt ) { int v = edge[i].v; if( edge[i].f && h[u] == h[v]+1 ) { int p = DFS( v, MIN( remain, edge[i].f )); edge[i].f -= p; edge[i^1].f += p; remain -= p; if( remain == 0 || h[s] == N ) return flow-remain; } } for(int i = head[u]; ~i; i = edge[i].nxt ) if( edge[i].f ) tmp = MIN( tmp, h[ edge[i].v ] ); if( !( --vh[ h[u] ] ) ) h[s] = N; else ++vh[ h[u] = tmp+1 ]; return flow-remain; } int sap() { int maxflow = 0; memset( h, 0, sizeof(h)); memset( vh, 0, sizeof(vh)); vh[0] = N; while( h[s] < N ) maxflow += DFS( s, inf ); return maxflow; } int main(){ int tt; scanf("%d", &tt); for(int Case = 1; Case <= tt; Case++){ scanf("%d%d", &n,&m); printf("Case #%d:\n", Case ); s = 1; t = n; N = n; int u, v, c; memset( head, 0xff, sizeof(head) ); idx = 0; for(int i = 1; i <= m; i++){ scanf("%d%d%d", &u, &v, &c); // if( u > v ) swap(u,v); AddEdge( u, v, c ); AddEdge( v, u, c ); int maxflow = sap(); if( maxflow > 0 ) printf("%d %d\n", i, maxflow ); } } return 0; }
Problem C
因为点只能在 y = 0 的轴上,其他点到当前点的距离则成为一个二次函数,开口向上。所以可以得出最小点即为我们所求。
所以可以三分求解。
View Code
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const double eps = 1e-8; const double Max = 1e10; const int N = 50005; struct Point{ double x, y; }p[N]; int n; int sgn(double x){ return x<-eps?-1:x>eps; } double Fabs(double x){ //return x<-eps?-x:x; return (sgn(x)<0)?-x: (x>eps?x:0); } double dist( Point a, Point b ){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } double function(double x){ Point a; a.x = x; a.y = 0; double res = 0; for(int i = 0; i < n; i++){ double tmp = dist( a, p[i] ); if( res < tmp ) res = tmp; } return res; } int main(){ int t; scanf("%d",&t); for(int ncase = 1; ncase <= t; ncase++){ scanf("%d",&n); double l = -10000., r = 10000.; for(int i = 0; i < n; i++){ scanf("%lf%lf",&p[i].x,&p[i].y); } double m, tm; while( (r-l)>eps ){ m = (l+r)/2.; tm = (m+r)/2.; if( function(m) < function(tm) ) r = tm; else l = m; } double ans = function(m); printf("Case #%d: %.6f\n",ncase, m); } return 0; }