uva10859Placing Lampposts

简介: 题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以他为一个端点的所有边,在灯的总数最小的前提下,被两盏灯同时照亮的边数应当尽量大。 分析:d(i,j)表示i的父节点放灯的状态为j(1表示放,0不放),以i为根的树的最小x值     x=Ma+c, a表...

题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以他为一个端点的所有边,在灯的总数最小的前提下,被两盏灯同时照亮的边数应当尽量大。

分析:d(i,j)表示i的父节点放灯的状态为j(1表示放,0不放),以i为根的树的最小x值     x=Ma+c, a表示灯的总数, c表示只有一盏灯照亮此边, 题目转化成求x最小的问题, 把每个节点的x都求出来就好

代码:

View Code
 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string.h>
 4 #include <vector>
 5 using namespace std;
 6 vector<int>adj[1010];
 7 int vis[1010][2], d[1010][2], n, m;
 8 #define DEBUG
 9 int dp(int i, int j, int f){
10     if(vis[i][j]) return d[i][j];
11     vis[i][j]=1;
12     int& ans=d[i][j];
13     int k;
14     
15     ans=2000;
16     for(k=0; k<adj[i].size(); k++)
17         if(adj[i][k]!=f) ans+=dp(adj[i][k], 1, i);
18     if(f>=0 && !j) ans++;
19 
20     if(f<0 || j){
21         int sum=0;
22         for(k=0; k<adj[i].size(); k++)
23             if(adj[i][k]!=f) sum+=dp(adj[i][k], 0, i);
24         if(f>=0) sum++;
25         if(ans>sum) ans=sum;
26     }
27     return ans;
28 }
29 int main(){
30 #ifndef DEBUG
31     freopen("in.txt", "r", stdin);
32 #endif
33     int T, a, b;
34     scanf("%d", &T);
35     while(T--){
36         scanf("%d%d", &n, &m);
37         int i;
38         for(i=0; i<n; i++) adj[i].clear();
39         for(i=0; i<m; i++){
40             scanf("%d%d", &a, &b);
41             adj[a].push_back(b);
42             adj[b].push_back(a);
43         }
44         memset(vis, 0, sizeof(vis));
45         int ans=0;
46         for(i=0; i<n; i++)
47             if(!vis[i][0]) ans+=dp(i, 0, -1);
48         printf("%d %d %d\n", ans/2000, m-ans%2000, ans%2000);
49     }
50     return 0;
51 }

训练指南上的分析表示我是第二遍看才看懂。不过上午交题目发现uva这题是judging error1.  ⊙﹏⊙b汗

目录
相关文章
|
5月前
|
Java
hdu 2503 a/b + c/d
hdu 2503 a/b + c/d
25 0
|
算法 Java 文件存储
|
人工智能
HDU1106
为了给学弟学妹讲课,我又水了一题…… 1: import java.util.*; 2: import java.io.*; 3: 4: public class HDU1106 5: { 6: public static void main...
857 0

热门文章

最新文章