SPOJ 13041 网络流+二分

SPOJ Problem Set (classical)

13041. The Black Riders

Problem code: AMR12A

 

'Hush!' said Frodo. 'I think I hear hoofs again.'
They stopped suddenly and stood as silent as tree-shadows, listening. There was a sound of hoofs in the lane, some way behind, but coming slow and clear down the wind. Quickly and quietly they slipped off the path, and ran into the deeper shade under the oak-trees.
The hoofs drew nearer. They had no time to find any hiding-place better than the general darkness under the trees. 
- Frodo, Sam and Pippin, when they encounter a Black Rider.
Indeed, the Black Riders are in the Shire, and they are looking for the One Ring. There are N hobbits out in their fields, but when they hear the Riders approaching, or feel the fear cast by their presence, they immediately wish to run and hide in M holes located nearby.
Now, each hole has space for just 1 hobbit; however, once a hobbit reaches a hole, he is able to make room for one more hobbit by digging away at the earth. The time required to make enough space for a second hobbit is C units. Also, each hole CANNOT hold more than 2 hobbits, even after digging. Also note that a hobbit can begin making space for the next hobbit only after he reaches the hole.
You are given the time required to travel from each hobbit's current location to each hole. Find the minimum amount of time it will take before at least K of the hobbits are hiding safely.
Input (STDIN):
The first line contains T, the number of test cases.
The first line of each test case contains 4 integers - N (no of hobbits), M (no of holes), K (minimum number of hobbits to hide) and C (time taken to expand a hole).
The next N lines contain M integers each, denoting the time taken for each hobbit to each hole.
Output (STDOUT):
Output one line per test case which contains the minimum time. 
Constraints:
1 <= T <= 6
1 <= N, M <= 100
1 <= K <= min(N, 2 * M)
0 < C < 10,000,000
0 < Time taken by the hobbits to the holes < 10,000,000
Time Limit: 2s
Memory Limit: 64MB
Sample Input:
2
3 3 2 10
9 11 13
2 10 14
12 15 12
4 3 3 8
1 10 100
1 10 100
100 100 6
12 10 10
Sample Output:
10
9
Notes/Explanation of Sample Input:
For the first test case, there are 3 hobbits and 3 holes, and we need to get atleast 2 of them to safety. We can send the first hobbit to the first hole, and the second hobbit to the second hole, thereby taking 10 time units.
For the second test case, we can make hobbit #1 reach hole 1 at time 1, hobbit #2 reach hole 1 at time 9 (by when hobbit #1 would have finished digging the hole), and hobbit #3 reach hole 3 at time 6.

'Hush!' said Frodo. 'I think I hear hoofs again.'

They stopped suddenly and stood as silent as tree-shadows, listening. There was a sound of hoofs in the lane, some way behind, but coming slow and clear down the wind. Quickly and quietly they slipped off the path, and ran into the deeper shade under the oak-trees.

The hoofs drew nearer. They had no time to find any hiding-place better than the general darkness under the trees. 

- Frodo, Sam and Pippin, when they encounter a Black Rider.

 

Indeed, the Black Riders are in the Shire, and they are looking for the One Ring. There are N hobbits out in their fields, but when they hear the Riders approaching, or feel the fear cast by their presence, they immediately wish to run and hide in M holes located nearby.

 

Now, each hole has space for just 1 hobbit; however, once a hobbit reaches a hole, he is able to make room for one more hobbit by digging away at the earth. The time required to make enough space for a second hobbit is C units. Also, each hole CANNOT hold more than 2 hobbits, even after digging. Also note that a hobbit can begin making space for the next hobbit only after he reaches the hole.

 

You are given the time required to travel from each hobbit's current location to each hole. Find the minimum amount of time it will take before at least K of the hobbits are hiding safely.

 

Input (STDIN):

 

The first line contains T, the number of test cases.

The first line of each test case contains 4 integers - N (no of hobbits), M (no of holes), K (minimum number of hobbits to hide) and C (time taken to expand a hole).

The next N lines contain M integers each, denoting the time taken for each hobbit to each hole.

 

Output (STDOUT):

 

Output one line per test case which contains the minimum time. 

 

Constraints:

1 <= T <= 6

1 <= N, M <= 100

1 <= K <= min(N, 2 * M)

0 < C < 10,000,000

0 < Time taken by the hobbits to the holes < 10,000,000

 

Sample Input:

2

3 3 2 10

9 11 13

2 10 14

12 15 12

4 3 3 8

1 10 100

1 10 100

100 100 6

12 10 10

 

Sample Output:

10

9

很巧妙的二分额~~~没想到啊!!!

#include <cstring>
#include <cstdio>
#include <queue>
#define MAXN 40000
#define MAXM 400000
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
    int u,v,f,c;
};
node e[MAXM];
int first[MAXN],next[MAXM];
int gap[MAXN],d[MAXN],curedge[MAXN],pre[MAXN];
int cc;
inline void add_edge(int u,int v,int f,int c)
{
    e[cc].u=u;
    e[cc].v=v;
    e[cc].f=f;
    e[cc].c=c;
    next[cc]=first[u];
    first[u]=cc;
    cc++;

    e[cc].u=v;
    e[cc].v=u;
    e[cc].f=0;
    e[cc].c=0;
    next[cc]=first[v];
    first[v]=cc;
    cc++;

}
int ISAP(int s,int t,int n)
{
    int cur_flow,flow_ans=0,u,tmp,neck,i,v;
    memset(d,0,sizeof(d));
    memset(gap,0,sizeof(gap));
    memset(pre,-1,sizeof(pre));
    for(i=0;i<=n;i++)
        curedge[i]=first[i];
    gap[0]=n+1;
    u=s;
    while(d[s]<=n)
    {
        if(u==t)
        {
            cur_flow=inf;
            for(i=s;i!=t;i=e[curedge[i]].v)
            {
                if(cur_flow>e[curedge[i]].f)
                {
                    neck=i;
                    cur_flow=e[curedge[i]].f;
                }
            }
            for(i=s;i!=t;i=e[curedge[i]].v)
            {
                tmp=curedge[i];
                e[tmp].f-=cur_flow;
                e[tmp^1].f+=cur_flow;
            }
            flow_ans+=cur_flow;
            u=neck;
        }
        for(i=curedge[u];i!=-1;i=next[i])
        {
            v=e[i].v;
            if(e[i].f&&d[u]==d[v]+1)
                break;
        }
        if(i!=-1)
        {
            curedge[u]=i;
            pre[v]=u;
            u=v;
        }
        else
        {
            if(0==--gap[d[u]])
                break;
            curedge[u]=first[u];
            for(tmp=n+5,i=first[u];i!=-1;i=next[i])
                if(e[i].f)
                    tmp=min(tmp,d[e[i].v]);
            d[u]=tmp+1;
            ++gap[d[u]];
            if(u!=s)
                u=pre[u];
        }
    }
    return flow_ans;
}
void build(int limit)
{
    int i;
    for(i=0;i<cc;i=i+2)
    {
        e[i].f=(e[i].c<=limit);
        e[i^1].f=0;
    }
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    {
        memset(first,-1,sizeof(first));
        memset(next,-1,sizeof(next));
        cc=0;
        int n,m,k,c;
        scanf("%d%d%d%d",&n,&m,&k,&c);
        int i,j;
        int s=0;
        int t=n+m+m+1;
        for(i=1;i<=n;i++)
        {
            add_edge(s,i,1,0);
            for(j=1;j<=m;j++)
            {
                int x;
                scanf("%d",&x);
                add_edge(i,n+j,1,x);
                add_edge(i,n+j+m,1,x+c);
            }
        }

        for(i=1;i<=m;i++)
        {
            add_edge(n+i,t,1,0);
            add_edge(n+i+m,t,1,0);
        }

        int l=0,mid;
        int r=20000010;
        int ans=inf;
        while(l<=r)
        {
            mid=(l+r)>>1;
            build(mid);
            int res=ISAP(s,t,t);
            if(res>=k)
            {
                if(res==k)
                {
                    ans=min(ans,mid);
                }
                r=mid-1;
            }
            else if(res<k)
                l=mid+1;
        }
        printf("%d\n",ans);
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值