zoukankan      html  css  js  c++  java
  • 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
    ",++ 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
    ",++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
    ",++ca ,ans) ;
        }
        return 0 ;
    }
    


    H。

    I。

    J,水题。

  • 相关阅读:
    实验二 Nmap的实践
    《网络攻击与防范》第八周学习总结
    《网络攻击与防范》第七周学习总结
    《网络攻击与防范》第六周学习总结
    《网络攻击与防范》第五周学习总结
    《网络攻击与防范》第四周学习总结
    《网络攻击与防范》第三周学习总结
    《网络攻击与防范》第二周学习总结
    Linux 基础入门学习总结
    20169312 2016-2017-2《网络攻防实践》课程总结
  • 原文地址:https://www.cnblogs.com/james1207/p/3297241.html
Copyright © 2011-2022 走看看