bzoj5154 [Tjoi2014]匹配

原创 2018年04月15日 18:10:39

http://www.elijahqi.win/archives/3100
Description

有N个单身的男孩和N个单身女孩,男孩i和女孩j在一起得到的幸福值为Hij。一个匹配即对这N个男孩女孩的安排:
每个男孩恰好有一个女朋友,每个女孩恰好有一个男朋友。一个匹配的幸福值即这N对男女朋友的幸福值的和。经
典的问题是计算幸福值最大的匹配,即完美匹配。然而完美匹配有时候并不唯一,你需要计算,对于所有的完美匹
配,其交集是什么。

Input

输入的第一行是一个正整数N。N ≤ 80
接下来是一个N*N大小的矩阵H,Hij表示男孩i和女孩j在一起的幸福值。(0≤Hij≤5000)

Output

第一行输出完美匹配的幸福值
接下来是若干行,每一行是一对整数i和j,表示男孩i和女孩j在所有完美匹配的交集中。以i的递增顺序输出

Sample Input

3
1 1 1
2 1 1
1 1 1
Sample Output

4
2 1
HINT

Source

一开始觉得暴力能过 仔细分析复杂度觉得有问题 但是还是写了T飞 然后仔细分析发现不需要n^2枚举边 只需要枚举那些有流量的边即可 然后AC

#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
#define pa pair<int,int>
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S)return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=gc();}
    while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
    return x*f;
}
const int N=200; bool flag[N];
int num=1,h[N],pre[N],path[N],dis[N],T;
struct node{
    int y,next,z,c;
}data[15000];
inline void insert1(int x,int y,int z,int c){
    data[++num].y=y;data[num].next=h[x];h[x]=num;data[num].z=z;data[num].c=c;
    data[++num].y=x;data[num].next=h[y];h[y]=num;data[num].z=0;data[num].c=-c;
}
inline bool spfa(){
    memset(pre,-1,sizeof(pre));memset(dis,0x80,sizeof(dis));
    queue<int>q;q.push(0);dis[0]=0;memset(flag,0,sizeof(flag));flag[0]=1;
    while(!q.empty()){
        int x=q.front();q.pop();flag[x]=0;
        for (int i=h[x];i;i=data[i].next){
            int y=data[i].y,z=data[i].z,c=data[i].c;
            if (dis[x]+c>dis[y]&&z){
                dis[y]=dis[x]+c;pre[y]=x;path[y]=i;
                if (!flag[y]){
                    q.push(y);flag[y]=1;
                }
            }
        }
    }return pre[T]!=-1;
}
pa q[10000];int top,n,a[88][88],ans,mp[88][88];
int main(){
    freopen("bzoj5154.in","r",stdin);
    n=read();T=(n<<1)+1;
    for (int i=1;i<=n;++i) insert1(0,i,1,0),insert1(i+n,T,1,0);
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j) a[i][j]=read(),insert1(i,j+n,1,a[i][j]);
    while(spfa()){
        int minn=inf,now=T;
        while(now) minn=min(minn,data[path[now]].z),now=pre[now];ans+=dis[T]*minn;now=T;
        while(now) data[path[now]].z-=minn,data[path[now]^1].z+=minn,now=pre[now];
    }
    for (int i=1;i<=n;++i){
        for (int j=h[i];j;j=data[j].next){
            int y=data[j].y;
            if(y>n&&y<T) mp[i][y-n]=data[j].z;
        }
    }
    for (int i=1;i<=n;++i){
        for (int j=1;j<=n;++j){
            if (mp[i][j]) continue;
            memset(h,0,sizeof(h));num=1;
            for (int ii=1;ii<=n;++ii) insert1(0,ii,1,0),insert1(ii+n,T,1,0);
            for (int i1=1;i1<=n;++i1){
                for (int j1=1;j1<=n;++j1){
                    if (i1==i&&j1==j) continue;
                    insert1(i1,j1+n,1,a[i1][j1]);
                }
            }int tmp=0,tmp1=0;
            while(spfa()){
                int minn=inf,now=T;
                while(now) minn=min(minn,data[path[now]].z),now=pre[now];tmp+=dis[T]*minn;now=T;tmp1+=minn;
                while(now) data[path[now]].z-=minn,data[path[now]^1].z+=minn,now=pre[now];
            }if (tmp!=ans&&tmp1==n) q[++top]=make_pair(i,j);
        }
    }printf("%d\n",ans);
    for (int i=1;i<=top;++i) printf("%d %d\n",q[i].first,q[i].second);
    return 0;
}
版权声明:辣鸡蒟蒻的blog https://blog.csdn.net/elijahqi/article/details/79951489

bzoj5154~bzoj5159 【TJOI2014】

bzoj5154 (Day1T1)匹配 【题意】 左右各nnn个点的二分图,求完美匹配的交集 【数据范围】 n≤80n≤80n\leq80 【思路】 求出一个完美匹配,再枚举完美匹配上每条...
  • leolyun
  • leolyun
  • 2018-02-12 10:57:40
  • 1364

【TJOI2014】匹配

Description对于100%的数据,N
  • lyd_7_29
  • lyd_7_29
  • 2017-03-29 21:05:10
  • 525

【JZOJ 3739】【TJOI2014】匹配

Description求一个二分图的最大费用最大流,并且求出哪些点必需要选。 n
  • HOWARLI
  • HOWARLI
  • 2017-03-25 15:00:59
  • 274

JZOJ 3739. 【TJOI2014】匹配

DescriptionInputOutputSample Input31 1 12 1 11 1 1Sample Output42 1Data Constraint对于30%的数据,N...
  • liyizhixl
  • liyizhixl
  • 2017-03-27 20:13:51
  • 175

tjoi2014二试试题、测试数据、选手程序、解题报告、标程

  • 2016年02月24日 18:17
  • 5.29MB
  • 下载

bzoj3445[Usaco2014 Feb] Roadblock 最短路(记录路径)

本来是一道傻叉题目,结果不认真看题被坑了。。 要求差最大,由于最短路不固定,所以要枚举而不能直接算出最长边然后*2,,我一开始floyd爆草结果WA了无数发。。后来才知道spfa直接枚举就好了。。 ...
  • qq_35866453
  • qq_35866453
  • 2017-06-03 21:51:39
  • 170

[JZOJ3743] 【TJOI2014】Alice and Bob

Description N
  • hzj1054689699
  • hzj1054689699
  • 2017-04-05 19:55:30
  • 550

【TJOI2014】[JZOJ3742] 上升子序列

Description 对于30%的数据,N
  • hzj1054689699
  • hzj1054689699
  • 2017-04-02 17:00:57
  • 597

【TJOI2014】电影评分(movie)

DescriptionInputOutput对于每个询问输出答案Sample Input10 R 1 1 1 R 2 2 1 2 C 2 2 R 3 1 2 Q 1 C 3 2 C 1 ...
  • u011056504
  • u011056504
  • 2017-04-01 22:01:35
  • 718

算法小结——KM算法

KM算法是应用较广的二分图匹配算法,效率较高,可以和费用流相媲美,而且比费用流简洁很多,思路也较为清晰,但是明显范围没有费用流广(费用流打得多的当我没说。。)这个算法基于匈牙利算法。 算法流程其实很...
  • qq_35866453
  • qq_35866453
  • 2017-03-25 16:02:00
  • 170
收藏助手
不良信息举报
您举报文章:bzoj5154 [Tjoi2014]匹配
举报原因:
原因补充:

(最多只允许输入30个字)