考虑费用流,题目要求走n个点都走完且恰好一次,显然流量的限制为n。

建立源点s和汇点t,并把每个星球拆成两个点i和i',分别表示已到达该点和经过该点。

对于能力爆发,建边(s,i',1,w). 对应高速航行,建边(s,i,1,0), (i,j',1,w).

因为每个点必须走一次且只能走一次。建边(i',t,1,0).

其实就是类似最小路径覆盖的建图方法。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{
int to, next, cap, flow, cost;
Edge(int _to=, int _next=, int _cap=, int _flow=, int _cost=):
to(_to), next(_next), cap(_cap), flow(_flow), cost(_cost){}
}edge[];
struct ZKW_MinCostMaxFlow{
int head[N], tot, cur[N], dis[N], ss, tt, n, min_cost, max_flow;
bool vis[N];
void init(){tot=; mem(head,-);}
void addedge(int u, int v, int cap, int cost){
edge[tot]=Edge(v,head[u],cap,,cost);
head[u]=tot++;
edge[tot]=Edge(u,head[v],,,-cost);
head[v]=tot++;
}
int aug(int u, int flow){
if (u==tt) return flow;
vis[u]=true;
for (int i=cur[u]; i!=-; i=edge[i].next) {
int v=edge[i].to;
if (edge[i].cap>edge[i].flow&&!vis[v]&&dis[u]==dis[v]+edge[i].cost) {
int tmp=aug(v,min(flow,edge[i].cap-edge[i].flow));
edge[i].flow+=tmp; edge[i^].flow-=tmp; cur[u]=i;
if (tmp) return tmp;
}
}
return ;
}
bool modify_label(){
int d=INF;
FO(u,,n) if (vis[u]) for (int i=head[u]; i!=-; i=edge[i].next) {
int v=edge[i].to;
if (edge[i].cap>edge[i].flow&&!vis[v]) d=min(d,dis[v]+edge[i].cost-dis[u]);
}
if (d==INF) return false;
FO(i,,n) if (vis[i]) vis[i]=false, dis[i]+=d;
return true;
}
PII mincostmaxflow(int start, int end, int nn){
ss=start, tt=end, n=nn; min_cost=max_flow=;
FO(i,,n) dis[i]=;
while () {
FO(i,,n) cur[i]=head[i];
while () {
FO(i,,n) vis[i]=false;
int tmp=aug(ss,INF);
if (tmp==) break;
max_flow+=tmp; min_cost+=tmp*dis[ss];
}
if (!modify_label()) break;
}
return mp(min_cost,max_flow);
}
}solve;
int main ()
{
int n, m, s, t, x, u, v;
scanf("%d%d",&n,&m);
s=; t=*n+;
solve.init();
FOR(i,,n) scanf("%d",&x), solve.addedge(s,i,,), solve.addedge(s,n+i,,x), solve.addedge(n+i,t,,);
FOR(i,,m) {
scanf("%d%d%d",&u,&v,&x);
if (u>v) swap(u,v);
solve.addedge(u,n+v,,x);
}
printf("%d\n",solve.mincostmaxflow(s,t,t+).first);
return ;
}

最新文章

  1. Codeforces 260 A - A. Laptops
  2. ListView实现Item局部刷新
  3. JavaFX(三)窗口拖动
  4. UITableView的简单使用
  5. 使用Maven构建Web项目的目录结构
  6. linux下sed命令对文件执行文本替换
  7. UVa 543 - Goldbach&#39;s Conjecture
  8. 以太仿DApp开发环境搭建
  9. 函数func_get_args详解
  10. Flink实战(1) - Apache Flink安装和示例程序的执行
  11. noip第19课资料
  12. 事务,acid,cap,paxos随笔
  13. 项目中调试SQLServer 方便的查看SQL语句的执行时间的方法
  14. PAT 甲级 1001 A+B Format
  15. 学习Spring Boot:(八)Mybatis使用分页插件PageHelper
  16. Syslink Control in MFC 9.0(转)
  17. boost.sha1
  18. 解决Ubuntu系统的每次开机重启后,resolv.conf清空的问题和DNS域名解析问题(图文详解)
  19. redis使用及配置之缓存详解
  20. Spark之 SparkSql整合hive

热门文章

  1. docker (2) 通用/镜像命令
  2. Git中分支merge和rebase的适用场景及区别
  3. 【调试】Linux下超强内存检测工具Valgrind
  4. LeetCode: 62. Unique Paths(Medium)
  5. VIO概述 On-Manifold Preintegration for Real-Time Visual--Inertial Odometry
  6. python3 爬虫爬取深圳公租房轮候库(深圳房网)
  7. Kotlin对象:仅一行代码就可创建安全的单例
  8. lesson 18 Electric currents in modern art
  9. Oracle作业练习题
  10. lintcode First Unique Number In Stream