首页 > 其他分享 >ZOJ 3348 Schedule(map运用+网络流之最大流)(竞赛问题升级版)

ZOJ 3348 Schedule(map运用+网络流之最大流)(竞赛问题升级版)

时间:2023-04-13 21:35:13浏览次数:42  
标签:map 3348 cur Schedule int cap cnt edge head


题目地址:ZOJ 3348

仍然是一道竞赛问题的网络流问题,但是这道题再用上次的竞赛建图方法就不行了,5000场比赛,明显会超时,于是需要换种建图思路了。上一道经典竞赛问题戳这里

上一道的胜负转换是利用专门给比赛建一个点,通过对比赛双方的流向来控制胜负关系,这里的建图方法更加巧妙(膜拜想出这个方法的大牛。。。),是先假设其中一方获胜,用mp[a][b]来表示a赢b的次数,将a与b连边,权值为mp[a][b],这样的话,前面的假设就仅仅只是假设而已,因为在这里,如果a的流量流向了b,说明a的胜利果实到了b,相当于b获胜。这是题解上的说法,但是我个人是理解的是在这里把比赛转换成了边(上一道是点),这条边连接比赛双方,然后这条边上的流量通过某一方从源点里加入都行,最后看从哪个端点流向了汇点就是相当于哪边赢,这是我个人的理解。

建图方法就是建一源点与汇点,每个人都与源点连边,权值为这个人将要获胜的场数,与汇点连边,权值为与DD的积分差-1,很明显是用来保证积分不超过DD的,然后将假设的胜负关系用有向边将各点连接起来。最后求一次最大流判断是否满流。对于每个人的转换处理,我是直接用的map映射,这样比较方便。

代码如下;


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int head[200], source, sink, nv, cnt;
int cur[200], num[200], d[200], pre[200], q[200], w[200], mp[200][200];
struct node
{
    int u, v, cap, next;
} edge[1000000];
void add(int u, int v, int cap)
{
    edge[cnt].v=v;
    edge[cnt].cap=cap;
    edge[cnt].next=head[u];
    head[u]=cnt++;

    edge[cnt].v=u;
    edge[cnt].cap=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
void bfs()
{
    memset(num,0,sizeof(num));
    memset(d,-1,sizeof(d));
    int f1=0, f2=0, i;
    d[sink]=0;
    num[0]=1;
    q[f1++]=sink;
    while(f1>=f2)
    {
        int u=q[f2++];
        for(i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(d[v]==-1)
            {
                d[v]=d[u]+1;
                num[d[v]]++;
                q[f1++]=v;
            }
        }
    }
}
int isap()
{
    memcpy(cur,head,sizeof(cur));
    bfs();
    int flow=0, u=pre[source]=source, i;
    while(d[source]<nv)
    {
        if(u==sink)
        {
            int f=INF,pos;
            for(i=source; i!=sink; i=edge[cur[i]].v)
            {
                if(f>edge[cur[i]].cap)
                {
                    f=edge[cur[i]].cap;
                    pos=i;
                }
            }
            for(i=source; i!=sink; i=edge[cur[i]].v)
            {
                edge[cur[i]].cap-=f;
                edge[cur[i]^1].cap+=f;
            }
            flow+=f;
            u=pos;
        }
        for(i=cur[u]; i!=-1; i=edge[i].next)
        {
            if(d[edge[i].v]+1==d[u]&&edge[i].cap)
                break;
        }
        if(i!=-1)
        {
            cur[u]=i;
            pre[edge[i].v]=u;
            u=edge[i].v;
        }
        else
        {
            if(--num[d[u]]==0) break;
            int mind=nv;
            for(i=head[u]; i!=-1; i=edge[i].next)
            {
                if(mind>d[edge[i].v]&&edge[i].cap)
                {
                    mind=d[edge[i].v];
                    cur[u]=i;
                }
            }
            d[u]=mind+1;
            num[d[u]]++;
            u=pre[u];
        }
    }
    return flow;
}
int main()
{
    int n, m, p, i, j, z;
    char s1[20], s2[20], s3[20];
    map<string,int>Q;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(w,0,sizeof(w));
        memset(head,-1,sizeof(head));
        cnt=0;
        z=1;
        Q.clear();
        char s4[20]="DD";
        Q[s4]=1;
        for(i=0; i<m; i++)
        {
            scanf("%s%s%s",s1,s2,s3);
            if(!Q[s1])
                Q[s1]=++z;
            if(!Q[s2])
                Q[s2]=++z;
            if(strcmp(s3,"win")==0)
            {
                w[Q[s1]]++;
            }
            else
            {
                w[Q[s2]]++;
            }
        }
        scanf("%d",&p);
        memset(mp,0,sizeof(mp));
        for(i=0; i<p; i++)
        {
            scanf("%s%s",s1,s2);
            if(!Q[s1])
                Q[s1]=++z;
            if(!Q[s2])
                Q[s2]=++z;
            if(Q[s1]==1||Q[s2]==1)
            {
                w[1]++;
            }
            else
            {
                mp[Q[s1]][Q[s2]]++;
                w[Q[s1]]++;
            }
        }
        int sum=0;
        for(i=2;i<=z;i++)
            sum+=w[i];
        source=0;
        sink=z;
        nv=sink+1;
        for(i=2; i<=z; i++)
        {
            add(source,i-1,w[i]);
            add(i-1,sink,w[1]-1);
            for(j=2; j<=z; j++)
            {
                add(i-1,j-1,mp[i][j]);
            }
        }
        int x=isap();
        //printf("%d\n",x);
        if(x==sum)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}



标签:map,3348,cur,Schedule,int,cap,cnt,edge,head
From: https://blog.51cto.com/u_16070138/6188414

相关文章

  • TreeMap源码
          常见面试题:    ......
  • Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not fi
    用idea使用mybatis时<mappers><mapperresource="com/mybatis/mapper/UserMapper.xml"></mapper></mappers>遇到吐下错误时ErrorparsingSQLMapperConfiguration.Cause:java.io.IOException:Couldnotfindresourcecom/my......
  • go语言基础-map
    0x00mapmap是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。0x00map的定义go语言当中map的定义map[KeyType]ValueType//KeyType:表示键的类型 //ValueType:表示键对应的值的类型。map类型的变量默认初始值为nil,需要使用make()函数来......
  • C++性能优化——能用array就不要用unordered_map作为查询表
    unordered_map需要哈希值计算和表查询的开销,当key值为整数且连续,直接用数组作为查询表具有更高的效率。#include<iostream>#include<chrono>#include<unordered_map>usingnamespacestd;longlongcount=0;constexprintN=10;voidtimeMeasure(void(*f)()){a......
  • map和applymap及apply的区别
    map和applymap及apply的区别1.数据importpandasaspdimportnumpyasnpframe=pd.DataFrame(np.random.rand(4,3),columns=list('abc'),index=['Utah','Ohio','Texas','Oregon'])print(frame)#输出如下:#......
  • 为什么HashMap的key允许空值,而Hashtable却不允许
    结论:HashMap对象的key、value值均可为null。      Hashtable对象的key、value值均不可为null。且两者的的key值均不能重复,若添加key相同的键值对,后面的value会自动覆盖前面的value,但不会报错。1.从源码分析HashMap从源码分析:  HashMap在put的时候会调用hash()......
  • Rust中的迭代器的使用:map转换、filter过滤、fold聚合、chain链接
    什么是迭代器Rust中的迭代器是一种强大的工具,它提供了一种灵活、通用的方法来遍历序列。迭代器是实现了Iteratortrait的类型,并需要至少实现一个next函数,用于让迭代器指向下一个迭代对象,并返回一个Option用于指示对象是否存在。fnnext(&mutself)->Option<Self::Item>;迭......
  • TreeMap
        ......
  • MultiValueMap在post请求中的使用
    如果data-form的方式处理post,有点区别,做个记录publicStringrobotSpeak(StringspeakMsg){log.info("机器人语音播报请求:{}",speakMsg);//headerHttpHeadersheaders=newHttpHeaders();headers.setContentType(MediaType.A......
  • Map<String, Map<String, String>>转String,再转回Map
    importorg.junit.Test;importjava.util.*;importjava.util.regex.Pattern;/****/publicclassTest2{@Testpublicvoidtest(){Map<String,String>testMap1=newHashMap<String,String>();testMap1.put("k......