Codeforces Beta Round #14 (Div. 2)

acm_cxlove發表於2013-03-15

轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

晚上 隊內訓練做的。。。難度適中

A:列舉每一個*,找到橫縱座標的最值

B:標記每一個點,然後再列舉

C:用map記錄頂點,每個頂點出現兩次,然後對於每一條線段,判斷一下是否和座標軸平行,
      然後判斷一下和某一個軸平行的是否是兩條

D:列舉每一條邊,斷開,成了兩個連通塊,然後分別對兩個連通塊求一次樹的直徑,乘積最大即解
struct Node{
    int u,v;
}e[200];
int n,a,b,ans,idx;
vector<int>v[205];
int bfs(int s){
    bool flag[205];
    int dist[205];
    mem(flag,false);
    queue<int>que;
    mem(dist,0);
    que.push(s);
    dist[s]=0;
    flag[s]=true;
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=0;i<v[u].size();i++){
            int m=v[u][i];
            if((u==a&&m==b)||(u==b&&m==a)) continue;
            if(flag[m]) continue;
            dist[m]=dist[u]+1;
            que.push(m);
            flag[m]=true;
        }
    }
    ans=0;
    for(int i=1;i<=n;i++)
        if(dist[i]>ans)
            ans=dist[i],idx=i;
    return ans==0?s:idx;
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&e[i].u,&e[i].v);
        v[e[i].u].pb(e[i].v);
        v[e[i].v].pb(e[i].u);
    }
    int answer=0;
    for(int i=0;i<n-1;i++){
        a=e[i].u;b=e[i].v;
        bfs(bfs(a));
        int ret=ans;
        bfs(bfs(b));
        ret*=ans;
        answer=max(answer,ret);
    }
    printf("%d\n",answer);
    return 0;
}



E:預處理出dp[i][j][k]表示對於一個峰,最左邊的y值是i,最右邊的y值是j,總共用了k個點的有多少種。
      然後ans[i][j][k]表示已經用了i個點組成j個峰,然後最後一個峰的最右點的y值是k的有多少種。
      很顯然的轉移,但是我是手打的表,TAT

相關文章