zoukankan      html  css  js  c++  java
  • BZOJ1927 [Sdoi2010]星际竞速 【费用流】

    1927: [Sdoi2010]星际竞速

    Time Limit: 20 Sec  Memory Limit: 259 MB
    Submit: 2582  Solved: 1601
    [Submit][Status][Discuss]

    Description

      10年一度的银河系赛车大赛又要开始了。作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的
    梦想,来自杰森座α星的悠悠也是其中之一。赛车大赛的赛场由N颗行星和M条双向星际航路构成,其中每颗行星都
    有一个不同的引力值。大赛要求车手们从一颗与这N颗行星之间没有任何航路的天体出发,访问这N颗行星每颗恰好
    一次,首先完成这一目标的人获得胜利。由于赛制非常开放,很多人驾驶着千奇百怪的自制赛车来参赛。这次悠悠
    驾驶的赛车名为超能电驴,这是一部凝聚了全银河最尖端科技结晶的梦幻赛车。作为最高科技的产物,超能电驴有
    两种移动模式:高速航行模式和能力爆发模式。在高速航行模式下,超能电驴会展开反物质引擎,以数倍于光速的
    速度沿星际航路高速航行。在能力爆发模式下,超能电驴脱离时空的束缚,使用超能力进行空间跳跃——在经过一
    段时间的定位之后,它能瞬间移动到任意一个行星。天不遂人愿,在比赛的前一天,超能电驴在一场离子风暴中不
    幸受损,机能出现了一些障碍:在使用高速航行模式的时候,只能由每个星球飞往引力比它大的星球,否则赛车就
    会发生爆炸。尽管心爱的赛车出了问题,但是悠悠仍然坚信自己可以取得胜利。他找到了全银河最聪明的贤者——
    你,请你为他安排一条比赛的方案,使得他能够用最少的时间完成比赛。

    Input

      第一行是两个正整数N,M。第二行N个数A1~AN,其中Ai表示使用能力爆发模式到达行星i所需的定位时间。接下
    来M行,每行3个正整数ui,vi,wi,表示在编号为ui和vi的行星之间存在一条需要航行wi时间的星际航路。输入数据
    已经按引力值排序,也就是编号小的行星引力值一定小,且不会有两颗行星引力值相同。

    Output

      仅包含一个正整数,表示完成比赛所需的最少时间。

    Sample Input

    3 3
    1 100 100
    2 1 10
    1 3 1
    2 3 1

    Sample Output

    12

    HINT

      说明:先使用能力爆发模式到行星1,花费时间1。然后切换到高速航行模式,航行到行星2,花费时间10。之

    后继续航行到行星3完成比赛,花费时间1。虽然看起来从行星1到行星3再到行星2更优,但我们却不能那样做,因

    为那会导致超能电驴爆炸。N≤800,M≤15000。输入数据中的任何数都不会超过106。输入数据保证任意两颗行星

    之间至多存在一条航道,且不会存在某颗行星到自己的航道。


    看到N的范围可以猜想这是一道网络流

    朝这个方面想,显然可以用费用流解决

    要保证每个点都访问,我们将每个点向T连边

    由于访问每个点有两种方式,我们这样建边:

    将每个点拆成Ai,Bi两点

    ①S->Bi,容量为1,费用为能力爆发模式费用【表示用能力爆发模式到达】

    ②Bi->T,容量1,费用0,表示到达这个点

    ③S->Ai,容量为1,费用为0,用以从这个点到达其他点

    ④Ai->Bj,容量1,费用为原边费用,表示通过i点到达j点

    一开始其实想着用S到i的INF流量的边,发现这样控不住费用,想了很久

    现在想想,既然是DAG图,每个点到达的点只有一个,我们只需开另一个点表示从这点出发即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
    using namespace std;
    const int maxn = 2005,maxm = 100005,INF = 1000000000;
    inline int RD(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
    	return out * flag;
    }
    int N,M,S,T;
    int vis[maxn],d[maxn],p[maxn],f[maxn];
    int head[maxn],nedge = 0;
    struct EDGE{int from,to,w,f,next;}edge[maxm];
    inline void build(int u,int v,int w,int f){
    	edge[nedge] = (EDGE){u,v,w,f,head[u]}; head[u] = nedge++;
    	edge[nedge] = (EDGE){v,u,-w,0,head[v]}; head[v] = nedge++;
    }
    int maxcost(){
    	int cost = 0,flow = 0,to,u;
    	queue<int> q;
    	while (true){
    		for (int i = 0; i <= T; i++) d[i] = INF;
    		d[S] = 0; f[S] = INF;
    		q.push(S);
    		while (!q.empty()){
    			u = q.front(); q.pop();
    			vis[u] = false;
    			Redge(u) if (edge[k].f && d[to = edge[k].to] > d[u] + edge[k].w){
    				d[to] = d[u] + edge[k].w;
    				f[to] = min(f[u],edge[k].f);
    				p[to] = k;
    				if (!vis[to]) q.push(to),vis[to] = true;
    			}
    		}
    		if (d[T] == INF) break;
    		flow += f[T];
    		cost += d[T] * f[T];
    		u = T;
    		while (u != S){
    			edge[p[u]].f -= f[T];
    			edge[p[u] ^ 1].f += f[T];
    			u = edge[p[u]].from;
    		}
    	}
    	return cost;
    }
    int main(){
    	memset(head,-1,sizeof(head));
    	N = RD(); M = RD();
    	S = 0; T = 2 * N + 1;
    	REP(i,N){
    		build(S,i,0,1);
    		build(S,N + i,RD(),1);
    		build(N + i,T,0,1);
    	}
    	int a,b,w;
    	while (M--){
    		a = RD(); b = RD(); w = RD();
    		if (a > b) swap(a,b);
    		build(a,N + b,w,1);
    	}
    	cout<<maxcost()<<endl;
    	return 0;
    }
    


  • 相关阅读:
    ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 17 电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282764.html
Copyright © 2011-2022 走看看