【BZOJ3291】Alice与能源计划

Description

在梦境中,Alice来到了火星。不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验。

为了方便,我们可以将火星抽象成平面,并建立平面直角坐标系。
火星上一共有N个居民点。每个居民点认为是平面上的一个点。第i个居民点的坐标为(Xi, Yi),对能源的需求量为Poweri。每个居民点消耗的能源由它附近的发电站提供。由于技术原因,一个居民点消耗的所有能源必须来自同一座发电站。
自人类移民火星之初,政府就有一个规模宏大的发电站建设计划。
按照这个计划,政府将在火星上建立M座发电站,这M座发电站将是火星居民的全部能量来源。其中,第i座发电站的坐标为(xi, yi),产生能量的上限值为Limiti,建设费用为Pricei。同样由于技术原因,第i座发电站只能为与它的距离不超过Ri的居民点提供能源。
然而,由于政府的财政状况一直十分紧张,截至目前,这M座发电站中只有少量建成并投入使用,多数的发电站尚未开始建设。

Alice的任务是修改这个计划,使得它更符合实际情况。根据新的规定,一座发电站产生的所有能源必须提供给同一个居民点。Alice知道这个规定意味着N个居民点消耗的能源将分别由N座不同的发电站提供,而且为第i个居民点提供能源的那座发电站的Limit值一定不小于Poweri。

Alice需要在原计划的M座发电站中选择恰好N座发电站,并完全放弃剩余的M - N座发电站,使得这N座发电站能够满足N个居民点的需要。
对于一个可行的方案,设方案中选择的N座发电站构成集合S,而已经建成的发电站构成集合T,那么定义这个方案的代价为

即,一个方案的代价等于被选择的且尚未建成的发电站的建设费用之和加上没有被选择的且已经建成的发电站的建设费用之和。

在所有可行方案中,你必须帮助Alice找到代价最小的方案,并将选择的N座发电站按编号从小到大的顺序输出。
如果代价最小的方案不唯一,则输出其中字典序最小的方案。

注意,输入文件包含多组测试数据。

Input

 第一行包含一个正整数T,表示有T组测试数据。接下来依次是T组测试数据。
  每组测试数据的第一行包含两个整数N、M。
  接下来N行,每行3个整数:Xi、Yi、Poweri
  再接下来M行,每行6个整数:xi、 yi、Limiti、Pricei、Ri、Finishedi。若Finished= 1,表示第i座发电站已经建成;否则Finishedi = 0,表示第i座发电站尚未开始建设。

Output

  对于每组测试数据:
  若存在可行方案则输出两行。第一行为一个整数,表示最小代价;第二行是若干个递增的整数,表示字典序最小的最优方案选择的发电站的编号。
  若不存在可行方案,则仅输出一行为一个整数-1。

Sample Input

4
1 1
4 4 1
8 7 1 2 5 1
2 3
0 0 3
2 0 2
1 1 5 1 3 0
1 0 5 1 1 1
3 0 5 1 3 0
2 3
0 0 3
2 0 2
1 1 2 0 3 0
1 0 1 0 1 1
3 0 3 0 2 0
2 3
0 0 3
2 0 2
1 1 4 2 2 0
1 0 2 9 1 1
3 0 5 4 2 1

Sample Output

0
1
1
1 2
-1
6
1 2
样例说明
  第1组测试数据:
  只有一个居民点,其坐标为(4, 4),能源需求量Power1 = 1;仅一座发电站,其坐标为(8, 7),产生的能量上限Limit1 = 1,建设费用Price1 = 2,服务范围半径R1 = 5,Finished1 = 1表示已经建成。
  两个点之间的距离等于5不超过R1,并且Power1 ≤ Limit1。因此唯一的可行方案是花费0的代价保留1号发电站,使它为1号居民点提供能源。
  第2组测试数据:任意选择两个发电站都是一个可行方案。最小代价是1,对应的方案有两种:选择1号和2号发电站;选择2号和3号发电站。而前者的字典序更小。
  第3组测试数据:不存在可行方案。
  第4组测试数据:代价最小的方案唯一:选择1号和2号发电站,代价为6。

HINT

  对于100%的数据:1 ≤ N ≤ 400,1 ≤ M ≤ 500,1 ≤ T ≤ 10,0 ≤ xi, yi , Xi , Yi, Pricei ≤ 10 000,1 ≤ Ri, Poweri, Limiti ≤ 10 000。不同的居民点或发电站的坐标有可能重合。

附注
  关于方案的字典序的大小关系的说明:
  设方案A选择的N座发电站的编号从小到大依次为A1, A2, …, AN;设方案B选择的N座发电站的编号从小到大依次为B1, B2, …, BN。
  我们称方案A比方案B字典序更小,当且仅当存在正整数i,满足1≤i≤N,使得对任意1≤k≤i-1有Ak = Bk,且Ai < Bi。

题解:看到题目和数据范围直接想到费用流,然后光荣TLE了,看题解发现是匈牙利~

首先,不选建成的发电站和选未建成的发电站都要付出代价,我们希望将代价都转换成:选择该发电站的代价。所以自然想到先假设所有简称的发电站都不选,然后选了它就会付出-Price的代价。然后本题就变成了一个二分图的带权匹配。

但是本题还有一个特殊的性质,就是一个发电站的所有出边的边权都是相等的。那么我们可以模拟费用流的方法,每次贪心的选取代价最小的发电站,如果代价相同则选取编号最小的。具体实现就是先排序,然后跑匈牙利即可。

rank2,感觉还不错~

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. int n,m,cnt,sum,ans;
  8. int head[510],vis[510],from[510],to[200010],next[200010];
  9. int X[510],Y[510],P[510];
  10. struct tower
  11. {
  12. int x,y,p,r,cost,org;
  13. }s[510];
  14. int rd()
  15. {
  16. int ret=0; char gc=getchar();
  17. while(gc<'0'||gc>'9') gc=getchar();
  18. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  19. return ret;
  20. }
  21. void add(int a,int b)
  22. {
  23. to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
  24. }
  25. bool cmp(tower a,tower b)
  26. {
  27. return (a.cost==b.cost)?(a.org<b.org):(a.cost<b.cost);
  28. }
  29. int dfs(int x)
  30. {
  31. for(int i=head[x];i!=-1;i=next[i])
  32. {
  33. if(!vis[to[i]])
  34. {
  35. vis[to[i]]=1;
  36. if(!from[to[i]]||dfs(from[to[i]]))
  37. {
  38. from[to[i]]=x;
  39. return 1;
  40. }
  41. }
  42. }
  43. return 0;
  44. }
  45. void work()
  46. {
  47. memset(head,-1,sizeof(head));
  48. memset(from,0,sizeof(from));
  49. sum=ans=cnt=0;
  50. n=rd(),m=rd();
  51. int i,j,flag=0;
  52. for(i=1;i<=n;i++) X[i]=rd(),Y[i]=rd(),P[i]=rd();
  53. for(i=1;i<=m;i++)
  54. {
  55. s[i].x=rd(),s[i].y=rd(),s[i].p=rd(),s[i].cost=rd(),s[i].r=rd();
  56. if(rd()) ans+=s[i].cost,s[i].cost=-s[i].cost;
  57. s[i].org=i;
  58. }
  59. sort(s+1,s+m+1,cmp);
  60. for(i=1;i<=m;i++) for(j=1;j<=n;j++)
  61. if(s[i].p>=P[j]&&(s[i].x-X[j])*(s[i].x-X[j])+(s[i].y-Y[j])*(s[i].y-Y[j])<=s[i].r*s[i].r)
  62. add(i,j);
  63. for(i=1;i<=m&&sum<n;i++)
  64. {
  65. memset(vis,0,sizeof(vis));
  66. sum+=dfs(i);
  67. }
  68. if(sum<n)
  69. {
  70. printf("-1\n");
  71. return ;
  72. }
  73. memset(vis,0,sizeof(vis));
  74. for(i=1;i<=n;i++) vis[s[from[i]].org]=1,ans+=s[from[i]].cost;
  75. printf("%d\n",ans);
  76. for(i=1;i<=m;i++)
  77. {
  78. if(vis[i])
  79. {
  80. if(flag) printf(" ");
  81. flag=1,printf("%d",i);
  82. }
  83. }
  84. printf("\n");
  85. }
  86. int main()
  87. {
  88. int T=rd();
  89. while(T--) work();
  90. return 0;
  91. }

【BZOJ3291】Alice与能源计划 二分图最大匹配的更多相关文章

  1. [bzoj3291] Alice与能源计划 (二分图最大匹配)

    传送门 Description 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系. ...

  2. 【bzoj3291】Alice与能源计划 模拟费用流+二分图最大匹配

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验. 为了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  3. BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  4. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  5. POJ2239 Selecting Courses(二分图最大匹配)

    题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...

  6. poj 2239 二分图最大匹配,基础题

    1.poj 2239   Selecting Courses   二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...

  7. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  8. 二分图最大匹配的K&#246;nig定理及其证明

     二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有.    以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上 ...

  9. POJ3057 Evacuation(二分图最大匹配)

    人作X部:把门按时间拆点,作Y部:如果某人能在某个时间到达某门则连边.就是个二分图最大匹配. 时间可以二分枚举,或者直接从1枚举时间然后加新边在原来的基础上进行增广. 谨记:时间是个不可忽视的维度. ...

随机推荐

  1. CSU 1505: 酷酷的单词【字符串】

    Description 输入一些仅由小写字母组成的单词.你的任务是统计有多少个单词是“酷”的,即每种字母出现的次数都不同.比如ada是酷的,因为a出现2次,d出现1次,而1和2不同.再比如,banan ...

  2. 暂停时间 以及dict 循环

    暂停时间 #!/usr/bin/python # -*- coding: UTF-8 -*- import time myD = {1: 'a', 2: 'b'} for key, value in ...

  3. 转:一个经典例子让你彻彻底底理解java回调机制

    一个经典例子让你彻彻底底理解java回调机制 转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273 ...

  4. DiSC小记

    最近在单位进行管理培训时进行了一个DiSC的心理测试,DiSC是Dominance,influence,Steadiness和Conscientiousness四个英文单词的首字母缩写.这四个单词对应 ...

  5. 深入SQL SERVER 2000的内存管理机制

    http://www.cnblogs.com/softj/articles/243591.html

  6. 【redis】redis实现API接口调用调用次数的限制

    redis实现API接口调用调用次数的限制 参考地址:https://bbs.csdn.net/topics/391856106?page=1 参考地址:https://www.cnblogs.com ...

  7. PE经典DIY案例1:全解开方案让量产PE也能

    更新说明:因未来的uefi似乎并不能识别并引导ud区,但能识别和引导量产和u+B+隐藏或高端隐藏区,故解决量产PE对u+B+隐藏区的支持,并增加对UEFI启动支持,已经成为PE制作的最主流技术. PE ...

  8. django中日志使用学习记录

    在setting中加入以下代码 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'verbose ...

  9. 时间迭代和BigDecimal操作

    常规小操作的代码: import java.math.BigDecimal; import java.sql.Timestamp; import java.text.SimpleDateFormat; ...

  10. 自主研发异步通信框架Minma(支持长连接和短连接)

    Minma是英文Minma Is Not Mina的简称 该框架采用Java NIO的核心技术,实现了基于事件驱动的多线程异步通信框架,支持常见的长连接(腾讯QQ)和短连接(http通信) 对于开发人 ...