首先我们可以知道这道题中每个点只能经过一次,那么我们引入附加源汇source,sink,那么我们可以将每个点拆成两个点,分别表示对于图中这个节点我们的进和出,那么我们可以连接(source,i,1,0),(i+n,sink,1,0),然后对于可以直接到达的点我们可以连接(source,i+n,1,cost)这个代表我们可以从任意一个点到达这个点,对于星球之间的连边我们可以连接(x,y+n,1,cost),代表我们可以从这个星球到另一个星球,因为我们考虑每个点只经过一次,所以可以这样构图,我们并不关心路径的具体方案,只关心这个点会被进一次,出一次。

 

/**************************************************************
    Problem: 1927
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:2388 ms
    Memory:1540 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 2010
#define maxm 40010
 
using namespace std;
 
int n,m,l,source,sink,ans;
int last[maxn],pre[maxm],other[maxm],len[maxm],cost[maxm];
int d[maxn],que[maxn*],vis[maxn],father[maxn];
 
void connect(int a,int b,int c,int d)
{
    pre[++l]=last[a];
    last[a]=l;
    other[l]=b;
    len[l]=c;
    cost[l]=d;
    //if (c) printf("|%d %d %d\n",a,b,d);
}
 
bool spfa()
{
    memset(d,0x3f,sizeof d);
    int h=,t=,cur;
    que[]=source; d[source]=;
    while (h<t)
    {
        cur=que[++h];
        vis[cur]=;
        for (int q=last[cur];q;q=pre[q])
        {
            if (!len[q]) continue;
            if (d[other[q]]>d[cur]+cost[q])
            {
                father[other[q]]=q;
                d[other[q]]=d[cur]+cost[q];
                if (!vis[other[q]])
                {
                    que[++t]=other[q];
                    vis[other[q]]=;
                }
            }
        }
    }
    return d[]!=d[sink];
}
 
void update()
{
    int cur=sink,low=<<;
    while (cur!=source)
    {
        low=min(low,len[father[cur]]);
        cur=other[father[cur]^];
    }
    cur=sink;
    while (cur!=source)
    {
        ans+=cost[father[cur]];
        len[father[cur]]-=low;
        len[father[cur]^]+=low;
        cur=other[father[cur]^];
    }
    //printf("%d\n",ans);
}
 
int main() {
    scanf("%d%d",&n,&m);
    source=(n<<)+; sink=source++; l=;
    for (int i=;i<=n;i++) {
        int x;
        scanf("%d",&x);
        connect(source,i+n,,x); connect(i+n,source,,-x);
    }
    for (int i=;i<=n;i++)   connect(source,i,,),connect(i,source,,);
    for (int i=;i<=m;i++) {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if (x>y) swap(x,y);
        connect(x,y+n,,z); connect(y+n,x,,-z);
    }
    for (int i=;i<=n;i++) connect(i+n,sink,,),connect(sink,i+n,,);
    while (spfa()) update();
    printf("%d\n",ans);
    return ;
}

bzoj 1927 网络流的更多相关文章

  1. Bzoj 1927: [Sdoi2010]星际竞速(网络流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec Memory Limit: 259 MB Description 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大 ...

  2. bzoj 1927 [Sdoi2010]星际竞速——网络流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1927 每个点拆点保证只经过一次. 主要是如果经过了这个点,这个点应该向汇点流过去表示经过了它 ...

  3. BZOJ 1927: [Sdoi2010]星际竞速

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2051  Solved: 1263[Submit][Stat ...

  4. BZOJ 1927 星际竞速(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1927 题意:一个图,n个点.对于给出的每条边 u,v,w,表示u和v中编号小的那个到编号 ...

  5. BZOJ 1927: [Sdoi2010]星际竞速 费用流

    1927: [Sdoi2010]星际竞速 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  6. bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1576  Solved: 954[Submit][Statu ...

  7. BZOJ 1927 星际竞速

    http://www.lydsy.com/JudgeOnline/problem.php?id=1927 思路:把一个点拆成两个点, S->i 费用0,流量1 (代表这个点可以移动到其他点所必备 ...

  8. BZOJ 1927: [Sdoi2010]星际竞速(最小费用最大流)

    拆点,费用流... ----------------------------------------------------------------------------- #include< ...

  9. BZOJ 1927: [Sdoi2010]星际竞速 [上下界费用流]

    1927: [Sdoi2010]星际竞速 题意:一个带权DAG,每个点恰好经过一次,每个点有曲速移动到他的代价,求最小花费 不动脑子直接上上下界费用流过了... s到点连边边权为曲速的代价,一个曲速移 ...

随机推荐

  1. C++并行编程2

    启动线程 查看线程构造函数,接受一个返回值为void的函数.如下: void do_some_work(); std::thread my_thread(do_some_work); 也可以接受一个重 ...

  2. error LNK2019: 无法解析的外部符号 该符号在函数 中被引用 解决方案

    需要添加lib或者dll库.项目-属性-配置属性-链接器-输入-附件依赖项,添加需要的lib. 例如我在运行OSG程序的时候,忘记添加了附件依赖项就会报这个错. 解决方案如图.

  3. Unity3d学习日记(四)

      跟着Unity的教程做了两天,做成了一个叫作survivalShooter的游戏,感觉还挺有意思的,做好后我就把它挂到了个人网站上.   如果你在我的网站的主页的话,点击这个图片就能跳到游戏界面. ...

  4. matlab如何将数组中的NAN值去除

        比如我们一组数据,里面有不少的NaN值,如何将其删除掉呢?可以通过find函数来搞定.     我们可以通过importdata('data.txt')将数据文件data.txt导入数组A中. ...

  5. 使用WebClient类对网页下载源码,对文件下载保存及异步下载并报告下载进度

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAx4AAAI7CAIAAADtTtpYAAAgAElEQVR4nO3dX6xlV33Y8f3UJFUqHq

  6. BZOJ 1996 合唱队(DP)

    考虑从最后的队形开始依次还原最初的队形. 对于当前的队形,要么选最左边的,要么选最右边的. 如果选了左边的,那么下次选择的一定是大于它的.右边的同理. 所以定义dp[mark][l][r]为区间[l, ...

  7. Java的第一个程序-Hello, World !

    学了一个月的Java,现在总结一下,就算复习了. 一.安装Java环境 这个没啥好说的. 1. 官网下载JDK安装 2. 配置环境变量.注意的是:环境变量配置好以后,如果cmd中运行 java 命令没 ...

  8. JavaScript词法分析解析

    函数在调用之前,会进行词法分析或者叫语法分析: 1. 函数在形成调用的那一瞬间,会有一个活动对象叫 active object ,简称AO,会分析如下几条: 形式参数 函数内局部变量声明 函数声明表达 ...

  9. javascript标准对象与包装对象

    javascript标准对象与包装对象 标准对象 在JavaScript的世界里,一切都是对象. 但是某些对象还是和其他对象不太一样.为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是 ...

  10. 【题解】Uoj79一般图最大匹配

    带花树裸题,感觉带花树强强……不会的勿看此文,解释的可能不对,只是给自己看的!!!如题,带花树即为求一般图最大匹配算法(匈牙利与dinic为二分图最大匹配).推荐论文:2015年<浅谈图的匹配算 ...