编程介的小学生 2017-02-09 16:42 采纳率: 20.5%
浏览 989
已采纳

Arrest

问题描述 :

There are (N+1) cities on TAT island. City 0 is where police headquarter located. The economy of other cities numbered from 1 to N ruined these years because they are all controlled by mafia. The police plan to catch all the mafia gangs in these N cities all over the year, and they want to succeed in a single mission. They figure out that every city except city 0 lives a mafia gang, and these gangs have a simple urgent message network: if the gang in city i (i>1) is captured, it will send an urgent message to the gang in city i-1 and the gang in city i -1 will get the message immediately.
The mission must be carried out very carefully. Once a gang received an urgent message, the mission will be claimed failed.
You are given the map of TAT island which is an undirected graph. The node on the graph represents a city, and the weighted edge represents a road between two cities(the weight means the length). Police headquarter has sent k squads to arrest all the mafia gangs in the rest N cities. When a squad passes a city, it can choose to arrest the gang in the city or to do nothing. These squads should return to city 0 after the arrest mission.
You should ensure the mission to be successful, and then minimize the total length of these squads traveled.
输入:

There are multiple test cases.
Each test case begins with a line with three integers N, M and k, here M is the number of roads among N+1 cities. Then, there are M lines. Each of these lines contains three integers X, Y, Len, which represents a Len kilometer road between city X and city Y. Those cities including city 0 are connected.
The input is ended by “0 0 0”.
Restrictions: 1 ≤ N ≤ 100, 1 ≤ M ≤ 4000, 1 ≤ k ≤ 25, 0 ≤ Len ≤ 1000
输出:

There are multiple test cases.
Each test case begins with a line with three integers N, M and k, here M is the number of roads among N+1 cities. Then, there are M lines. Each of these lines contains three integers X, Y, Len, which represents a Len kilometer road between city X and city Y. Those cities including city 0 are connected.
The input is ended by “0 0 0”.
Restrictions: 1 ≤ N ≤ 100, 1 ≤ M ≤ 4000, 1 ≤ k ≤ 25, 0 ≤ Len ≤ 1000
样例输入:

3 4 2
0 1 3
0 2 4
1 3 2
2 3 2
0 0 0
样例输出:

14

  • 写回答

2条回答 默认 最新

  • devmiao 2017-02-13 18:08
    关注
     #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    #include<iomanip>
    using namespace std;
    typedef long long ll;
    const   int oo=1e9;
    const   int mm=11111111;
    const   int mn=888888;
    int node,src,dest,edge;
    int ver[mm],flow[mm],cost[mm],nex[mm];
    int head[mn],dis[mn],p[mn],q[mn],vis[mn];
    /**这些变量基本与最大流相同,增加了
     cost 表示边的费用,
     p 记录可行流上节点对应的反向边
     */
    void prepare(int _node,int _src,int _dest)
    {
        node=_node,src=_src,dest=_dest;
        for(int i=0; i<node; i++)head[i]=-1,vis[i]=0;
        edge=0;
    }
    void addedge(int u,int v,int f,int c)
    {
        ver[edge]=v,flow[edge]=f,cost[edge]=c,nex[edge]=head[u],head[u]=edge++;
        ver[edge]=u,flow[edge]=0,cost[edge]=-c,nex[edge]=head[v],head[v]=edge++;
    }
    /**以上同最大流*/
    /**spfa 求最短路,并用 p 记录最短路上的边*/
    bool spfa()
    {
        int i,u,v,l,r=0,tmp;
        for(i=0; i<node; ++i)dis[i]=oo;
        dis[q[r++]=src]=0;
        p[src]=p[dest]=-1;
        for(l=0; l!=r; (++l>=mn)?l=0:l)
            for(i=head[u=q[l]],vis[u]=0; i>=0; i=nex[i])
                if(flow[i]&&dis[v=ver[i]]>(tmp=dis[u]+cost[i]))
                {
                    dis[v]=tmp;
                    p[v]=i^1;
                    if(vis[v]) continue;
                    vis[q[r++]=v]=1;
                    if(r>=mn)r=0;
                }
        return p[dest]>-1;
    }
    /**源点到汇点的一条最短路即可行流,不断的找这样的可行流*/
    int SpfaFlow()
    {
        int i,ret=0,delta;
        while(spfa())
        {
            for(i=p[dest],delta=oo; i>=0; i=p[ver[i]])
                if(flow[i^1]<delta)delta=flow[i^1];
            for(i=p[dest]; i>=0; i=p[ver[i]])
                flow[i]+=delta,flow[i^1]-=delta;
            ret+=delta*dis[dest];
        }
        return ret;
    }
    int tu[110][110];
    
    void floyd(int n)
    {
        for(int k=0; k<=n; k++)
            for(int i=0; i<=n; i++)
                for(int j=0; j<=n; j++)
                    tu[i][j]=min(tu[i][j],tu[i][k]+tu[k][j]);
    }
    
    int main()
    {
        int n,m,k;
        while(~scanf("%d%d%d",&n,&m,&k)&&n+m+k)
        {
            int st=2*n+1,ed=2*n+2;
            prepare(2*n+3,st,ed);
            for(int i=0; i<=n; i++)
                for(int j=0; j<=n; j++)
                    tu[i][j]=i==j?0:oo;
            while(m--)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                if(c<tu[a][b])
                    tu[a][b]=tu[b][a]=c;
            }
            floyd(n);
            addedge(st,0,k,0);
            addedge(0,ed,k,0);
            for(int i=1; i<=n; i++)
                addedge(0,i,1,tu[0][i]),addedge(i,i+n,1,-100000),addedge(i+n,ed,1,tu[i][0]);
            for(int i=1; i<=n; i++)
                for(int j=i+1; j<=n; j++)
                    addedge(i+n,j,1,tu[i][j]);
            printf("%d\n",SpfaFlow()+100000*n);
        }
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)