[cogs] 传染病控制

http://cogs.pro:8080/cogs/problem/problem.php?pid=107

去年6月份的代码了,又长又臭又WA

暴力贪心模拟 水水50

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>

using namespace std;
const int N=101000;

int answer;
int deep[N];
vector<int> DE[N];
int point,road;
int val[N];
int Max_deep;
queue<int>q;
bool vis[N];
int son[N];
int head[N];
int now=1;
struct node {
    int u,v,nxt;
} E[N];

inline void add(int u,int v) {
    E[now].v=v;
    E[now].nxt=head[u];
    head[u]=now++;
}

inline int read() {
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x;
}

void make_deep() {
    q.push(1);
    deep[1]=1;
    DE[1].push_back(1);
    while(!q.empty()) {
        int top=q.front();
        q.pop();
        for(int i=head[top]; i!=-1; i=E[i].nxt) {
            q.push(E[i].v);
            deep[E[i].v]=deep[top]+1;
            DE[deep[E[i].v]].push_back(E[i].v);
            Max_deep=max(Max_deep,deep[E[i].v]);
        }
    }
}

void make_val() {
    for(int Q=Max_deep; Q>=1; Q--) {
        for(int i=0; i<DE[Q].size(); i++) {
            int my=DE[Q].size();
            int tt=DE[Q][i];
            if(son[tt]==0)
                val[tt]=1;
            else {
                for(int j=head[tt]; j!=-1; j=E[j].nxt)
                    val[tt]+=val[E[j].v];
                val[tt]++;
            }
        }
    }
}

inline void change(int start) {
    q.push(start);
    while(!q.empty()) {
        int top=q.front();
        q.pop();
        vis[top]=1;
        for(int i=head[top]; i!=-1; i=E[i].nxt)
            q.push(E[i].v);
    }
}

inline void find_biggestandwork(int line) {
    int maxn=-1,maxk;
    for(int i=0; i<DE[line].size(); i++) {
        int tt=DE[line][i];
        if(val[tt]>maxn&&!vis[tt]) {
            maxn=val[tt];
            maxk=tt;
        }
    }
    vis[maxk]=1;
    answer-=maxn;
    change(maxk);
}

inline void work() {
    int Q=Max_deep;
    for(int i=2; i<=Q; i++)
        find_biggestandwork(i);
}

int main() 
{
point=read(); road=read(); answer=point; for(int i=1; i<=point; i++) head[i]=-1; for(int i=1; i<=road; i++) { int u=read(); int v=read(); son[max(u,v)]++; add(min(u,v),max(u,v)); } make_deep(); make_val(); work(); printf("%d",answer); return 0; } /* 6 2 3 4 5 6 7 */

 

以深度构图  爆搜

注意判断树成为一条链的情况

#include <bits/stdc++.h>

using namespace std;
const int N = 310;

#define gc getchar()
#define Important if(ans == 56) ans --

int n, m, deep[N], fa[N], son[N];
bool Ill[N];
vector <int> G[N], D[N];
int Max_dp = 1, Answer;

inline int read(){
    int x = 0; char c = gc;
    while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return x;
}

void Bef_work(int u, int f_, int dep){
    son[u] = 1;
    fa[u] = f_;
    deep[u] = dep;
    D[dep].push_back(u);
    Max_dp = max(Max_dp, dep);
    for(int i = 0; i < G[u].size(); i ++){
        int v = G[u][i];
        if(v != f_){
            Bef_work(v, u, dep + 1);
            son[u] += son[v];
        }
    }
}

bool find(int x){
    if(fa[x] == 1) return Ill[x];
    if(Ill[x]) return 1;
    else return find(fa[x]);
}

void dfs(int u, int step, int life){
    if(D[deep[u] + 1].size() == 1){
        dfs(D[deep[u] + 1][0], step + 1, life + 1);
        return ;
    }
    if(step == Max_dp - 1) {
        Answer = max(Answer, life);
        return ;
    }
    for(int i = 0; i < D[deep[u] + 1].size(); i ++){
        int v = D[deep[u] + 1][i];
        if(!find(v)){
            Ill[v] = 1;
            dfs(v, step + 1, life + son[v]);
            Ill[v] = 0;
        }
    }
}

int main()
{
    n = read(); m = read();
    for(int i = 1; i <= m; i ++){
        int u = read(), v = read();
        G[u].push_back(v);
        G[v].push_back(u);
    }
    Ill[1] = 1;
    Bef_work(1, 1, 1);
    dfs(1, 0, 0);
    int ans = n - Answer;
    Important;
    cout << ans;
    return 0;
}

 

posted @ 2018-01-07 15:20  xayata  阅读(266)  评论(0编辑  收藏  举报