Placing Lampposts

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=91212#problem/E

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

vector<int> adj[1010];
int vis[1010][2],d[1010][2],n,m;

int dp(int i,int j,int f)
{
    if(vis[i][j]) return d[i][j];
    vis[i][j]=1;
    int &ans=d[i][j];

    ans=2000;
    for(int k=0;k<adj[i].size();k++)
    {
        if(adj[i][k]!=f)
            ans+=dp(adj[i][k],1,i);
    }
    if(j==0&&f>=0) ans++;

    if(j||f<0)          //如果这个点已经放了灯或者这个点是根节点就不放灯
    {
        int sum=0;
        for(int k=0;k<adj[i].size();k++)
        {
            if(adj[i][k]!=f)
                sum+=dp(adj[i][k],0,i);
        }
        if(f>=0) sum++;
        ans=min(ans,sum);
    }
    return ans;
}

int main()
{
    int T,a,b;
    scanf("%d",&T);
    while(T--)
    {
     scanf("%d%d",&n,&m);              //n个点,m条边
     for(int i=0;i<n;i++) adj[i].clear();
     for(int i=0;i<m;i++)
     {
      scanf("%d%d",&a,&b);
      adj[a].push_back(b);
      adj[b].push_back(a);          //无向图
     }
     memset(vis,0,sizeof(vis));
     int ans=0;
     for(int i=0;i<n;i++)
     {
         if(!vis[i][0])            //一颗未曾处理的新树
            ans+=dp(i,0,-1);        //i代表树的根节点,0代表不放灯,-1代表它没有父节点
     }
     cout<<ans/2000<<" "<<m-ans%2000<<" "<<ans%2000<<endl; //输出 a m-c c
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zsyacm666666/p/4894972.html