130829 周赛

Regionals 2012 :: Asia - Jakarta

UVA地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=559

A。搜索就行了,水题。

 

#define N 55

int a[N][N] ;

int n , m ;

bool vis[N][N] ;

int inmap(int x ,int y){

    if(x >= 0 && x < n && y >= 0 && y < m)return 1 ;return 0 ;

}

int mx[4] = {0 , 0, 1 , -1} ;

int my[4] = {1 , -1, 0 , 0} ;



int ans = 0 ;

void dfs(int x , int y){

    int fk = 0 ;

    for (int i = 0 ; i < 4;  i ++ ){

        int tx = x + mx[i] ;

        int ty = y + my[i] ;

        if(inmap(tx ,ty) && a[x][y] > a[tx][ty]){

            vis[tx][ty] = 1 ;

            dfs(tx , ty) ;

            vis[tx][ty] = 0 ;

            fk ++ ;

        }

    }

    if(!fk)ans ++ ;

}

int main() {

    int T ;

    cin >> T ;

    int ca = 0 ;

    while(T -- ){

        cin >> n >> m ;

        for (int i = 0 ; i < n ; i ++ ){

            for (int j = 0 ; j < m ; j ++ )cin >> a[i][j] ;

        }

        ans = 0 ;

        for (int i = 0 ; i < n ; i ++ ){

            for (int j = 0 ; j < m ; j ++ ){

                int snum = 0 ;

                int hnum = 0 ;

                mem(vis ,0) ;

                for (int k = 0 ; k < 4 ; k ++ ){

                    int tx = i + mx[k] ;

                    int ty = j + my[k] ;

                    if(inmap(tx , ty)){

                        snum ++ ;

                        if(a[i][j] >= a[tx][ty])hnum ++ ;

                    }

                }

                vis[i][j] = 1 ;

                if(snum == hnum)dfs(i , j) ;

            }

        }

        printf("Case #%d: %d\n",++ ca , ans) ;

    }

    return 0 ;

}


B,

 

首先我们假设这个点从父节点过来的流量是x ,那么这个流量肯定是要流向其他点的。

那么是哪些点呢,我们要具体判断一下,首先我们找出出父节点过来边的其他流量的总和,和最大流量。

然后对于这个最大流量,我们要判断一下,一开始我就只这里没判断导致WA了,这里要判断最大流量是否大于剩余的流量,如果是的话,那么我们就可以将父节点的流量全部流进这里,然后从这里流出最大流量-父节点流量,那么答案就加上这个流量即可。

如果小于的话,那么我们只要判断父节点的流量是否大于剩余的总流量,如果大于,那么无所谓,答案就不加,因为父节点的流量可以流满所有的点,如果小于,我们只要把这个流量减去父节点的流量,然后将剩余流量两两配对即可,即x / 2 + x % 2 。

这样就很清楚了,一个DFS就可以了。

 

#include <set>

#include <map>

#include <stack>

#include <cmath>

#include <queue>

#include <cstdio>

#include <string>

#include <vector>

#include <iomanip>

#include <cstring>

#include <iostream>

#include <algorithm>

#define Max 2505

#define FI first

#define SE second

#define ll long long

#define PI acos(-1.0)

#define inf 0x3fffffff

#define LL(x) ( x << 1 )

#define bug puts("here")

#define PII pair<int,int>

#define RR(x) ( x << 1 | 1 )

#define mp(a,b) make_pair(a,b)

#define mem(a,b) memset(a,b,sizeof(a))

#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )



using namespace std;



inline void RD(int &ret) {

    char c;

    int flag = 1 ;

    do {

        c = getchar();

        if(c == '-')flag = -1 ;

    } while(c < '0' || c > '9') ;

    ret = c - '0';

    while((c=getchar()) >= '0' && c <= '9')

        ret = ret * 10 + ( c - '0' );

    ret *= flag ;

}



inline void OT(int a) {

    if(a >= 10)OT(a / 10) ;

    putchar(a % 10 + '0') ;

}



inline void RD(double &ret) {

    char c ;

    int flag = 1 ;

    do {

        c = getchar() ;

        if(c == '-')flag = -1 ;

    } while(c < '0' || c > '9') ;

    ll n1 = c - '0' ;

    while((c = getchar()) >= '0' && c <= '9') {

        n1 = n1 * 10 + c - '0' ;

    }

    ll n2 = 1 ;

    while((c = getchar()) >= '0' && c <= '9') {

        n1 = n1 * 10 + c - '0' ;

        n2 *= 10 ;

    }

    ret = flag * (double)n1 / (double)(n2) ;

}

/*********************************************/



#define             N                   1111111

int n ;

struct kdq {

    int s , e,  l, next ;

} ed[N] ;

int head[N] , num ;

void init() {

    mem(head, -1) ;

    num = 0 ;

}

void add(int s ,int e ,int l) {

    ed[num].s = s ;

    ed[num].e = e ;

    ed[num].l = l ;

    ed[num].next = head[s] ;

    head[s] = num ++ ;

}



bool vis[N] ;

int x[N] ;

int in[N] ;

int ans = 0 ;

void dfs(int now ,int fa ,int pre){

    int sum = 0 ;

    int MX = 0 ;

    int pos = 0 ;

    for (int i = head[now] ; ~i ; i = ed[i].next ){

        int e = ed[i].e ;

        int l = ed[i].l ;

        if(e == fa)continue ;

        dfs(e , now , l) ;

        sum += l ;

        if(MX < l){

            MX = l ;

            pos = e ;

        }

    }

    if(MX > sum - MX + pre )ans += MX - pre ;

    else if(sum >= pre)ans += (sum - pre ) / 2 + (sum - pre) % 2 ;



}

int main() {

    int T ;

    cin >> T ;

    int ca = 0 ;

    while (T -- ) {

        cin >> n ;

        init() ;

        mem(in, 0) ;

        mem(vis ,0) ;

        int a , b , c ;

        int dd = 0 ;

        for (int i = 0 ; i < n - 1 ; i ++ ) {

            RD(a) ;

            RD(b) ;

            RD(c) ;

            add(a , b , c) ;

            add(b , a , c) ;

            in[a] ++ ;

            in[b] ++ ;

        }



        ans = 0 ;

        dfs(1 , 0 , 0) ;

        printf("Case #%d: %d\n",++ca , ans) ;

    }

    return 0 ;

}


C。水题。

 

 

#define N 10

int a[2] ,b[2],c[2] , d[2],e[2] ;

int main() {

    int T ;

    cin >> T  ;

    int ca = 0 ;

    while(T -- ){

        int sum = 0 ;

        cin >> a[0] >> b[0] >> c[0] >> d[0] >> e[0] ;

        sum += a[0] + b[0] + c[0] + d[0] + e[0] ;

        int M ;

        cin >> M ;

        printf("Case #%d: ",++ca) ;

        if(sum >= M){

            cout << "0" << endl; continue ;

        }

        int num = 0 ;

        bool flag = 0 ;

        int x = 1 ;

        while(1){

            a[num ^ 1] = a[num] + b[num] ;

            b[num ^ 1] = b[num] + c[num] ;

            c[num ^ 1] = c[num] + d[num] ;

            d[num ^ 1] = d[num] + e[num] ;

            e[num ^ 1] = e[num] + a[num] ;

            int ss = a[num ^ 1] + b[num ^ 1] + c[num ^ 1] + d[num ^ 1] + e[num ^ 1] ;

            if(ss >= M)break ;

            else if(ss <= sum){

                flag = 1 ;break ;

            }

            x ++ ;

            num ^= 1 ;

        }



        if(flag)cout << -1 << endl;

        else cout << x << endl;

    }

    return 0 ;

}

D。

 

E。

F。


G。

直接求出双连通分量,然后缩点之后,对于点数大于等于2的连通分量是不能访问的,所以只要找出所有连通的点数为1的双联通分量的数量,然后C(n , 2)就可以了。

 

#define N 11111

struct kdq{

    int e ,next ;

    int sign ;

}ed[N * 20] , ed1[N * 20] ;

int head[N] , num ;

int head1[N] , num1 ;

void add(int s ,int e){

    ed[num].e = e ;

    ed[num].next = head[s] ;

    ed[num].sign = 0 ;

    head[s] = num ++ ;

}

void add1(int s ,int e){

    ed1[num1].e = e ;

    ed1[num1].next = head1[s] ;

    ed1[num1].sign = 0 ;

    head1[s] = num1 ++ ;

}

int n , m ;

int dfn[N] , low[N] , belong[N] , st[N] ,cnt[N] ,vis[N] ;

int tp , dp , scc ;

void init(){

    mem(head ,-1) ;

    mem(head1, -1) ;

    num1 = 0 ;

    num = 0 ;

    mem(dfn ,-1) ;

    mem(low ,0) ;

    mem(belong ,0) ;

    mem(st ,0) ;

    mem(cnt ,0) ;

    tp = dp = scc = 0 ;

}

void tarjan(int now , int fa){

    dfn[now] = low[now] = ++ dp ;

    st[tp ++ ] = now ;

    vis[now] = 1 ;

    for (int i = head[now] ; ~i ; i = ed[i].next ){

        int e = ed[i].e ;

        if(ed[i].sign)continue ;

        ed[i].sign = ed[i ^ 1].sign = 1 ;

        if(e == fa)continue ;

        if(dfn[e] == -1){

            tarjan(e , now) ;

            low[now] = min(low[e] , low[now]) ;

        }

        else if(vis[e]){

            low[now] = min(low[now] , dfn[e]) ;

        }

    }

    if(dfn[now] == low[now]){

        scc ++ ;

        int xx ;

        do{

            xx = st[-- tp] ;

            belong[xx] = scc ;

            cnt[scc] ++ ;

            vis[xx] = 0 ;

        }while(xx != now) ;

    }

}

int sum = 0 ;

void dfs(int now){

    for (int i = head1[now] ; ~i ; i = ed1[i].next){

        int e = ed1[i].e ;

        if(!vis[e]){

            sum ++ ;

            vis[e] = 1 ;

            dfs(e) ;

        }

    }

}

int main() {

    int T ;

    cin >> T ;

    int ca = 0 ;

    while( T -- ){

        cin >> n >> m ;

        init() ;

        while(m -- ){

            int a , b ;

            RD(a) ; RD(b) ;

            add(a , b) ;add(b, a) ;

        }

        for (int i = 1 ; i <= n ; i ++ )if(dfn[i] == -1)tarjan(i ,-1) ;

        mem(vis ,0) ;

        for (int i = 1 ; i <= n ; i ++ ){

            for (int j = head[i] ; ~j ; j = ed[j].next ){

                int x = belong[i] ;

                int y = belong[ed[j].e] ;

                if(x != y){

                    add1(x , y) ;add1(y ,x) ;

                }

            }

        }

        for (int i = 1 ; i <= scc ; i ++ ){

            if(cnt[i] >= 2)vis[i] = 1 ;

        }

        ll ans = 0 ;

        for (int i = 1 ; i <= scc ; i ++ ){

            if(!vis[i] && cnt[i] == 1){

                sum = 1 ;

                vis[i] = 1 ;

                dfs(i) ;

                ans += (ll)sum * (sum - 1) / 2 ;

            }

        }

        printf("Case #%d: %lld\n",++ca ,ans) ;

    }

    return 0 ;

}


H。

 

I。

J,水题。

 

你可能感兴趣的:(130829 周赛)