编程之美初赛第二场

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;
}

 

posted @ 2013-04-14 21:29  yefeng1627  阅读(273)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor