编程之美初赛第二场

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;

}

 

你可能感兴趣的:(编程之美)