问题描述:
1021. Safe Fruit (35)
There are a lot of tips telling us that some fruits must not be eaten with some other fruits, or we might get ourselves in serious trouble. For example, bananas can not be eaten with cantaloupe (哈密瓜), otherwise it will lead to kidney deficiency (肾虚).
Now you are given a long list of such tips, and a big basket of fruits. You are supposed to pick up those fruits so that it is safe to eat any of them.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: N, the number of tips, and M, the number of fruits in the basket. both numbers are no more than 100.
Then two blocks follow. The first block contains N pairs of fruits which must not be eaten together, each pair occupies a line and there is no duplicated tips; and the second one contains M fruits together with their prices, again each pair in a line. To make it simple, each fruit is represented by a 3-digit ID number. A price is a positive integer which is no more than 1000. All the numbers in a line are separated by spaces.
Output Specification:
For each case, first print in a line the maximum number of safe fruits. Then in the next line list all the safe fruits, in increasing order of their ID's. The ID's must be separated by exactly one space, and there must be no extra space at the end of the line. Finally in the third line print the total price of the above fruits. Since there may be many different solutions, you are supposed to output the one with a maximum number of safe fruits. In case there is a tie, output the one with the lowest total price. It is guaranteed that such a solution is unique.
Sample Input:16 20 001 002 003 004 004 005 005 006 006 007 007 008 008 003 009 010 009 011 009 012 009 013 010 014 011 015 012 016 012 017 013 018 020 99 019 99 018 4 017 2 016 3 015 6 014 5 013 1 012 1 011 1 010 1 009 10 008 1 007 2 006 5 005 3 004 4 003 6 002 1 001 2Sample Output:
12 002 004 006 008 009 014 015 016 017 018 019 020 239
直接dfs+剪枝就行了,顺便感谢一下 dalao给出的关于”dp[i]数组保存编号为i的水果后能得到的的最大水果个数“的剪枝思路http://blog.csdn.net/bendaai
(第一次写blog,有点方)
ac代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
#include<bits/stdc++.h> using namespace std; struct node { set<int> s; int p; int dp; bool v; } no; map<int,node> m; vector<set<int> > v; vector<int> vb,vr,vn; int mnum,msum; void dfs(set<int>::iterator its,int num,int sum,int vi,int vj) { if(its==v[vi].end()) { if(num>mnum||(num==mnum&&sum<msum)) { vr=vb; mnum=num; msum=sum; } return; } else if(num+v[vi].size()-vj<mnum) return; else if(num+m[*its].dp<mnum&&m[*its].dp>0) return; else { int kk,k=*its; if(!vb.empty()) kk=vb.back(); if(!m[k].v) { set<int>::iterator itss; vector<int> vl; for(itss=m[k].s.begin();itss!=m[k].s.end();++itss) if(!m[*itss].v) { m[*itss].v=true; vl.push_back(*itss); } vb.push_back(k); ++its; dfs(its,num+1,sum+m[k].p,vi,vj+1); --its; if(vb.size()>1) { if(m[k].dp+1>m[kk].dp) m[kk].dp=m[k].dp+1; } vb.pop_back(); for(int i=0;i<vl.size();i++) m[vl[i]].v=false; } ++its; dfs(its,num,sum,vi,vj+1); --its; if(vb.size()>1) { if(m[k].dp+1>m[kk].dp) m[kk].dp=m[k].dp+1; } } } void bfs() { queue<int> q; map<int,node>::iterator itm; set<int>::iterator its; for(itm=m.begin();itm!=m.end();++itm) { if((itm->second).v) { (itm->second).v=false; int vs=v.size(); set<int> sv; v.push_back(sv); v[vs].insert(itm->first); q.push(itm->first); for(;!q.empty();q.pop()) { int k=q.front(); for(its=m[k].s.begin();its!=m[k].s.end();++its) { if(m[*its].v) { m[*its].v=false; v[vs].insert(*its); q.push(*its); } } } } } } int main() { // ios::sync_with_stdio(false); // freopen("data.txt","r",stdin); int n,k,c1,c2,x,p1,p2,c=0,t=0; scanf("%d %d",&n,&k); mnum=0,msum=0; for(;n--;) { scanf("%d %d",&c1,&c2); m[c1].s.insert(c2); m[c2].s.insert(c1); } for(;k--;) { scanf("%d %d",&c1,&c2); m[c1].p=c2; m[c1].v=true; m[c1].dp=0; } bfs(); int mmn=0,mms=0; for(int i=0;i<v.size();i++) { mnum=0,msum=0; dfs(v[i].begin(),0,0,i,0); mmn+=mnum; mms+=msum; for(int i=0;i<vr.size();i++) vn.push_back(vr[i]); } sort(vn.begin(),vn.end()); printf("%d\n%03d",mmn,vn[0]); for(int i=1;i<vn.size();i++) printf(" %03d",vn[i]); printf("\n%d",mms); return 0; } |