首页 > 代码库 > HDU 4354
HDU 4354
思路是在看电视时突然想到的。枚举区间,然后按树形DP来选择最大值看是否满足条件。但枚举区间时的方法低效,看了题解,说枚举区间可以设两个指针逐步移动,
开始 l = r = 1, 记录已经出现的国家。
判断是否满足条件。
如果满足,更新答案,更新区间出现的国家,l++, 一直到不满足。
如果不满足,更新区间出现的国家,r++, 一直到满足。
但我写了好久,呃,没正确。。。。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int C,N,K,M,cnt,tot;struct City{ int x,belong;};City cities[5050];int head[2050];int dp[2050][2];bool vis[2050];struct node{ int u,v; int next;}edge[6500];bool cmp(City a,City b){ if(a.x<b.x) return true; return false;}int belong[2050];void addedge(int u,int v){ edge[tot].u=u; edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++;}void dfs(int u,int f){ dp[u][0]=0;dp[u][1]=1; vis[u]=true; for(int ei=head[u];ei!=-1;ei=edge[ei].next){ if(f!=edge[ei].v&&belong[edge[ei].v]>0&&!vis[edge[ei].v ]){ dfs(edge[ei].v,u); dp[u][1]+=dp[edge[ei].v][0]; dp[u][0]+=max(dp[edge[ei].v][0],dp[edge[ei].v][1]); } }}bool judge(){ int ans=0; memset(vis,false,sizeof(vis)); for(int i=1;i<=N;i++){ if(!vis[i]&&belong[i]>0){ dfs(i,0); ans+=max(dp[i][0],dp[i][1]); } } if(ans>=K) return true; else return false;}int main(){ int T,t=0,u,v,l,r; scanf("%d",&T); while(++t<=T){ scanf("%d%d%d%d",&C,&N,&K,&M); cnt=tot=0; for(int i=1;i<=C;i++){ scanf("%d%d",&cities[i].x,&cities[i].belong); } memset(head,-1,sizeof(head)); sort(cities+1,cities+1+C,cmp); for(int i=1;i<=M;i++){ scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } cnt=l=r=1; int ans=-1; memset(belong,0,sizeof(belong)); while(r<=C){ if(cnt>=K && judge()){ if(ans==-1||cities[r].x - cities[l].x<ans) ans=cities[r].x - cities[l].x; belong[ cities[l].belong ]--; if( belong[ cities[l].belong ]==0 ) cnt--; l++; } else{ r++; belong[ cities[r].belong ]++; if( belong[ cities[r].belong ]==1 ) cnt++; } } printf("Case #%d: %d\n",t,ans); } return 0;}
下面是别人过了的代码。。。T_T不知道错哪里了
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int C = 5005;const int N = 2005;const int M = 1005;int cnt[N]; //i????????int vis[C];int dp[C][2];int c, n, k, m;vector<int>v[N];struct city{ int x, y; bool operator<(const city &a) const { return x<a.x; }}ct[C];int min(int x, int y){ if(x==-1) return y; return x<y?x:y;}void dfs(int s){ vis[s] = 1; dp[s][1] = 1; dp[s][0] = 0; for(int i=0; i<v[s].size(); i++) { int ss = v[s][i]; if(vis[ss]==1 || cnt[ss]==0) continue; dfs(ss); dp[s][1] += dp[ss][0]; dp[s][0] += max(dp[ss][1], dp[ss][0]); }}bool ok(int l, int r){ int res = 0; memset(vis, 0, sizeof(vis)); for(int i = l; i<=r; i++) if(vis[ ct[i].y ]==0) { dfs( ct[i].y ); res += max( dp[ ct[i].y ][0], dp[ ct[i].y ][1] ); } if(res>=k) return true; else return false;}int solve(){ int kk, l, r; kk = l = r = 1; cnt[ ct[1].y ]++; int ans = -1; while(r<=c) { if(kk>=k && ok(l, r)) { ans = min(ans, ct[r].x - ct[l].x); cnt[ ct[l].y ]--; if( cnt[ ct[l].y ]==0 ) kk--; l++; } else { r++; cnt[ ct[r].y ]++; if( cnt[ ct[r].y ]==1 ) kk++; } } return ans;}int main(){ int t, tt=0, i, x, y; scanf("%d", &t); while(t--) { scanf("%d%d%d%d", &c, &n, &k, &m); for(i=1; i<=n; i++) v[i].clear(); memset(cnt, 0, sizeof(cnt)); memset(vis, 0, sizeof(vis)); for(i=1; i<=c; i++) scanf("%d%d", &ct[i].x, &ct[i].y); sort(ct+1, ct+1+c); for(i=1; i<=m; i++) { scanf("%d%d", &x, &y); v[x].push_back(y); v[y].push_back(x); } printf("Case #%d: %d\n", ++tt, solve()); } return 0;}
HDU 4354
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。