poj 3686 KM

来源:互联网 发布:云计算协会 编辑:程序博客网 时间:2024/05/17 01:08

题意:工场加工玩句的时间给你,两个玩具不能同时在一个工场加工,求平均时间最短,每个玩具从开始到加工完成的时间才叫总时间,不仅仅是它加工的时间,应该包括等待时间。

解法:KM算法, 建图很神奇,一直不能理解正确性,哎,太悲剧了。

    比如样例

   1

   2   2

   3  8

   2  8

建立的图形为

   -3 -6 -8 -16

   -2 -4 -8 -16

   最佳匹配为-3-4=-7,平均时间为3.5分钟,确实是正确答案,但是按照正常的来说应该是2+5才对啊。

   只能去意淫这种建图的正确性了:加工的批次不同,他们的加数都是3 2 2,建图很神奇,YY功力严重不足。

/*----------------------------------   Love is more than a word.   It says so much.   When I see these four letters,   I almost feel your touch.   This is only happened since   I fell in love with you.   Why this word does this,   I haven't got a clue.                   To My Goddess                          CY----------------------------------*/#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#include <queue>#define maxn 26000+5#define maxm 155#define ull unsigned long long #define ll long long#define reP(i,n) for(i=1;i<=n;i++) #define REP(i,a,b) for(i=a;i<=b;i++)  #define rep(i,n) for(i=0;i<n;i++)#define cle(a) memset(a,0,sizeof(a)) #define clehead(a) rep(i,maxn)a[i]=-1/*  The time of story :  **  while(1)    {         once upon a time,         there was a mountain,         on top of which there was a temple,         in which there was an old monk and a little monk.         Old monk was telling stories inside the temple.         What was he talking about?  **  }   ÎûÎû   (*^__^*)*/#define sci(a) scanf("%d",&a) #define scd(a) scanf("%lf",&a)  #define pri(a) printf("%d",a)   #define prie(a) printf("%d\n",a)    #define prd(a)  printf("%lf",a)     #define prde(a) printf("%lf\n",a)      #define pre printf("\n")#define LL(x) x<<1 #define RR(x) x<<|1#define pb push_back#define mod 90001#define PI 3.141592657const ull INF = 1LL << 61;const int inf =   int(1e5)+10;const double eps=1e-5;using namespace std;struct node{   int u,v,w;   int next;};bool cmp(int a,int b){    return a>b;}int val[maxm][maxm];int mat[maxm][maxn],match1[maxn],match2[maxn];int km(int m,int n){    int s[maxn],t[maxn],l1[maxn],l2[maxn],p,q,ret=0,i,j,k;    rep(i,m){        for(l1[i]=-inf,j=0;j<n;j++)l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];        if(l1[i]==-inf)return -1;    }    for(i=0;i<n;l2[i++]=0);    memset(match1,-1,sizeof(match1));    memset(match2,-1,sizeof(match2));    for(i=0;i<m;i++)    {        memset(t,-1,sizeof(t));        for(s[p=q=0]=i;p<=q&&match1[i]<0;p++)        {            for(k=s[p],j=0;j<n&&match1[i]<0;j++)            {                if(l1[k]+l2[j]==mat[k][j]&&t[j]<0)                {                    s[++q]=match2[j],t[j]=k;                    if(s[q]<0)                    {                        for(p=j;p>=0;j=p)                        {                            match2[j]=k=t[j],p=match1[k],match1[k]=j;                        }                    }                }            }        }                if(match1[i]<0)                {                    for(i--,p=inf,k=0;k<=q;k++)                    {                        for(j=0;j<n;j++)                        {                            if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)                            {                                p=l1[s[k]]+l2[j]-mat[s[k]][j];                            }                        }                    }                    for(j=0;j<n;l2[j]+=t[j]<0?0:p,j++);                    for(k=0;k<=q;l1[s[k++]]-=p);                }    }    for(i=0;i<m;i++)    {        ret+=mat[i][match1[i]];    }    return ret;}int main(){    freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,m;    int T;    cin>>T;    while(T--)    {        cin>>n>>m;        int i,j,k;        rep(i,n)        rep(j,m)        {            scanf("%d",&val[i][j]);        }        rep(i,n){           rep(j,m)           {               rep(k,n)               {                   mat[i][j*n+k]=-(val[i][j]*(k+1));               }           }        }        rep(i,n)        {            rep(j,m*n)            {                cout<<mat[i][j]<<" ";            }            cout<<endl;        }        m*=n;        printf("%.6f\n",-((double)km(n,m))/(n*1.0));    }    return 0;}


0 0
原创粉丝点击