Sending Secret Messages 费用流模板

题目:

Alice wants to send Bob some confidential messages. But their internet connection is not secured enough. As their names have been used in many networking schemes, they are very rich now. So, they don't want to send encoded messages, they want to use secured dedicated connection for them. So, they talked to some ISPS (Internet Service Providers) about their problem. Only they get is that there are N routers in the network, some of them share bidirectional links. Each link has a capacity, and for each KB of data passing through this link, they have to pay some money. Assume that Alice is connected with the 1st router and Bob is connected to the Nth router.

For example, in the picture, Alice wants to send 4 KB data from router 1 to router 6. Each link is identified by two integers in the form (a, b) where 'a' denotes the capacity of the link and 'b' denotes per KB cost of the link. So, Alice can send 1KB of data through 1 - 2 - 3 - 4 - 6 (cost 8), 2KB data through 1 - 5 - 6 (cost 2 * 9=18) and 1KB data through 1 - 3 - 4 - 6 (cost 11). So, the total cost is 37 units.

Now Alice wants to send P KB of data to Bob. You have to find the minimum amount of money they have to pay to achieve their goal.

输入:

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with a blank line. Next line contains three integers N (2 ≤ N ≤ 50), M (0 ≤ M ≤ N*(N-1)/2) and P (1 ≤ P ≤ 1000), where M denotes the number of bidirectional links. Each of the next M lines contains four integers u v w c (1 ≤ u, v ≤ N, u ≠ v, 1 ≤ w, c ≤ 100), meaning that there is a link between router u and v, and at most c KB data can be sent through this link, and each KB of data through this link will cost w. You can assume that there will be at most one connection between a pair of routers.

输出:

For each case, print the case number and the minimum amount of money required or "impossible" if it's not possible to send P KB of data.

样例输入:

3

 

6 9 4

3 1 9 8

1 2 1 2

1 5 6 1

5 6 2 8

6 4 2 2

4 2 7 6

2 6 7 9

3 4 5 1

3 2 2 3

 

6 9 9

3 1 9 8

1 2 1 2

1 5 6 1

5 6 2 8

6 4 2 2

4 2 7 6

2 6 7 9

3 4 5 1

3 2 2 3

 

4 4 20

1 3 1 3

3 4 1 4

1 2 1 2

2 4 1 5

样例输出:

Case 1: 37

Case 2: 139

Case 3: impossible

 一个模板题,但是做的时候还是有点困难,做题太少了。。

给出一个图,规定源点为1,汇点为给出的要输入的N。给出费用和容量,问从源点到汇点运送PkB花费最小费用是多少,如果不能运送完Pkb,则输出impossible。注意无向图要建两次边。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=60000;
const int INF=0x3f3f3f3f;
int head[maxn],dis[maxn],pre[maxn],vis[maxn];//dis是到这个点需要的费用,pre是当前点的前一个点
int cnt;
struct edge
{
    int u,v,cap,cost,next;
}node[maxn<<1];
void add(int u,int v,int cost,int cap)
{
    node[cnt].u=u;
    node[cnt].v=v;
    node[cnt].cost=cost;
    node[cnt].cap=cap;
    node[cnt].next=head[u];
    head[u]=cnt++;

    node[cnt].u=v;
    node[cnt].v=u;
    node[cnt].cost=-cost;
    node[cnt].cap=0;
    node[cnt].next=head[v];
    head[v]=cnt++;
}
int maxflow(int s,int t,int p)
{
    int res=0;
    while(p>0)
    {
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(pre,-1,sizeof(pre));
        queue<int>q;
        dis[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=node[i].next)
            {
                edge e=node[i];
                if(e.cap>0&&dis[e.v]>dis[e.u]+e.cost)
                {
                    dis[e.v]=dis[e.u]+e.cost;
                    pre[e.v]=i;
                    if(!vis[e.v])
                    {
                        q.push(e.v);
                        vis[e.v]=1;
                    }

                }
            }
            vis[u]=0;
        }
        if(dis[t]==INF)return -1;//如果到达不了汇点,则返回-1;
        int d=p;
        for(int i=pre[t];i!=-1;i=pre[node[i].u])
            d=min(d,node[i].cap);//找到这条路径上最短的那一块
        p-=d;
        res+=d*dis[t];//走这条路径需要的花费
        for(int i=pre[t];i!=-1;i=pre[node[i].u])
        {
            node[i].cap-=d;
            node[i^1].cap+=d;
        }
    }
    return res;
}
int main()
{
    int t,N,M,P;
    scanf("%d",&t);
    int cas=0;
    while(t--)
    {
        memset(head,-1,sizeof(head));
        cnt=0;
        scanf("%d%d%d",&N,&M,&P);
        for(int i=1;i<=M;i++)
        {
            int u,v,w,c;
            scanf("%d%d%d%d",&u,&v,&w,&c);
            add(u,v,c,w);
            add(v,u,c,w);
        }
        int res=maxflow(1,N,P);
        if(res==-1)//如果没有到达汇点,就是到t的费用是INF,然后返回到这里-1
            printf("Case %d: impossible\n",++cas);
        else
            printf("Case %d: %d\n",++cas,res);
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
最小费用最大是一个经典的网络问题,可以使用MATLAB来解决。MATLAB中有许多网络算法的实现,其中包括最小费用最大算法。以下是一个简单的MATLAB代码,可以用来解决最小费用最大问题: ```matlab function [f, cost] = min_cost_max_flow(C, s, t, demand) % C: cost matrix, C(i,j) is the cost of sending one unit of flow from i to j % s: source node % t: sink node % demand: demand vector, demand(i) is the demand at node i % f: flow matrix, f(i,j) is the flow from i to j % cost: the minimum cost of sending the required demand n = size(C, 1); % number of nodes f = zeros(n); % initialize flow matrix while true % find shortest path from s to t using the Bellman-Ford algorithm [dist, prev] = bellman_ford(C, s); if dist(t) == inf % if there is no path from s to t, terminate break end % initialize residual capacity matrix res_cap = zeros(n); for i = 1:n for j = 1:n res_cap(i,j) = C(i,j) - f(i,j); end end % find the bottleneck capacity bottleneck = demand(t); node = t; while node ~= s bottleneck = min(bottleneck, res_cap(prev(node), node)); node = prev(node); end % update flow matrix and demand vector node = t; while node ~= s f(prev(node), node) = f(prev(node), node) + bottleneck; f(node, prev(node)) = f(node, prev(node)) - bottleneck; demand(node) = demand(node) - bottleneck; demand(prev(node)) = demand(prev(node)) + bottleneck; node = prev(node); end end % calculate minimum cost cost = 0; for i = 1:n for j = 1:n cost = cost + f(i,j) * C(i,j); end end end function [dist, prev] = bellman_ford(C, s) % C: cost matrix, C(i,j) is the cost of sending one unit of flow from i to j % s: source node % dist: distance vector, dist(i) is the shortest distance from s to i % prev: predecessor vector, prev(i) is the node that precedes i on the shortest path from s to i n = size(C, 1); % number of nodes dist = inf(1, n); % initialize distance vector prev = zeros(1, n); % initialize predecessor vector dist(s) = 0; % distance from source to source is zero for k = 1:n-1 % iterate n-1 times for i = 1:n for j = 1:n if C(i,j) ~= 0 && dist(i) + C(i,j) < dist(j) dist(j) = dist(i) + C(i,j); prev(j) = i; end end end end end ``` 这个代码实现了最小费用最大算法,其中使用了Bellman-Ford算法来寻找最短路径。你可以根据自己的需求来调整代码,并在MATLAB中运行它。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值