{KM}

 

update(2018-01-20):

发现暑假的时候真是zz。。。

学了好久也不是很理解,今天一下就看懂了。。。

之前还以为不用slack的方法更快,理解了之后发现没用slack数组的写法都是错的orz。。。很巧合的过了一些题。。。zz

 



 

 

Ants

 UVALive - 4043 

这题真是心态崩了

一开始犯了一个致命的错误始终没发现,WA了十几发完全无解

索性重新写了一遍,结果一直TLE,一共交了将近30发

早上起来试着加上slack数组,结果过了。。。

之前一直觉得slack数组没什么用的,竟然会超时。。。

然后忽然也发现了昨天那个错误。。。

本来很简单的一道题。。。orz心态崩了

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const double inf=1e30;
 4 const int maxv=110;
 5 double c[maxv][maxv];
 6 int vb[maxv],vg[maxv];
 7 double eb[maxv],eg[maxv];
 8 int mc[maxv];
 9 double d;
10 int n;
11 int ll[maxv];
12 struct node
13 {
14     int x,y;
15 }b[maxv],w[maxv];
16 double getdis(int i,int j)
17 {
18     int dx=b[i].x-w[i].x;
19     int dy=b[i].y-w[i].y;
20     return sqrt(dx*dx+dy*dy);
21 }
22 bool eq(double a,double b)
23 {
24     return  fabs(a-b)<1e-9;
25 }
26 int dfs(int x)
27 {
28     vg[x]=1;
29     for(int i=0;i<n;i++)
30     {
31         if(vb[i]) continue;
32        
33         double gap=eg[x]+eb[i]-c[x][i];
34         if(eq(gap,0))
35         {
36              vb[i]=1;
37             if(mc[i]==-1||dfs(mc[i]))
38             {
39                 ll[x]=i;
40                 mc[i]=x;
41                 return 1;
42             }
43         }
44         else d=min(d,gap);
45     }
46     return 0;
47 }
48 void KM()
49 {
50     memset(mc,-1,sizeof(mc));
51     memset(eb,0,sizeof(eb));
52     for(int i=0;i<n;i++)
53     {
54         eg[i]=c[i][0];
55         for(int j=1;j<n;j++)
56             eg[i]=max(eg[i],c[i][j]);
57     }
58 
59     for(int i=0;i<n;i++)
60     {
61         while(1)
62         {
63             memset(vb,0,sizeof(vb));
64             memset(vg,0,sizeof(vg));
65             d=inf;
66         
67             if(dfs(i)) break;
68             for(int i=0;i<n;i++)
69             {
70                 if(vb[i]) eb[i]+=d;
71                 if(vg[i]) eg[i]-=d;
72             }
73         }
74     }
75 }
76 int main()
77 {
78     int kase=0;
79     while(scanf("%d",&n)!=EOF)
80     {
81         for(int i=0;i<n;i++)
82             scanf("%d%d",&b[i].x,&b[i].y);
83         for(int i=0;i<n;i++)
84             scanf("%d%d",&w[i].x,&w[i].y);
85         for(int i=0;i<n;i++)
86             for(int j=0;j<n;j++)
87             c[i][j]=-getdis(i,j);
88         KM();
89       //  if(kase++) puts("");
90         for(int i=0;i<n;i++) printf("%d\n",ll[i]+1);
91     }
92 
93 }
deadly版
 1 #include <bits/stdc++.h>
 2 using namespace  std;
 3 const int maxv=210;
 4 int n;
 5 struct node
 6 {
 7     int x,y;
 8 }a[maxv],b[maxv];
 9 
10 double c[maxv][maxv];
11 double eg[maxv],eb[maxv];
12 int vb[maxv],vg[maxv];
13 int mc[maxv];
14 double d;
15 
16 bool eq(double x,double y)
17 {
18     return fabs(x-y)<1e-10;
19 }
20 int dfs(int x)
21 {
22     vg[x]=1;
23     for(int i=0;i<n;i++)
24     {
25         if(vb[i]) continue;
26         if(eq(eg[x]+eb[i],c[x][i]))
27         {
28             vb[i]=1;
29             if(mc[i]==-1||dfs(mc[i]))
30             {
31                 mc[i]=x;
32                 return 1;
33             }
34         }
35         else d=min(d,eg[x]+eb[i]-c[x][i]);
36     }
37     return 0;
38 }
39 void KM()
40 {
41     memset(mc,-1,sizeof(mc));
42     memset(eb,0,sizeof(eb));
43     for(int i=0;i<n;i++)
44     {
45         eg[i]=c[i][0];
46         for(int j=1;j<n;j++)
47             eg[i]=max(eg[i],c[i][j]);
48     }
49     for(int i=0;i<n;i++)
50     {
51         while(1)
52         {
53             memset(vb,0,sizeof(vb));
54             memset(vg,0,sizeof(vg));
55             d=1e20;
56             if(dfs(i)) break;
57             for(int i=0;i<n;i++)
58             {
59                 if(vb[i]) eb[i]+=d;
60                 if(vg[i]) eg[i]-=d;
61             }
62         }
63     }
64 }
65 
66 int main()
67 {
68     while(scanf("%d",&n)!=EOF)
69     {
70         for(int i=0;i<n;i++) scanf("%d%d",&b[i].x,&b[i].y);
71         for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
72         for(int i=0;i<n;i++)
73             for(int j=0;j<n;j++)
74         {
75             double x=a[i].x-b[j].x;
76             double y=a[i].y-b[j].y;
77             c[i][j]=-sqrt(x*x+y*y);
78         }
79         KM();
80         for(int i=0;i<n;i++)
81             printf("%d\n",mc[i]+1);
82     }
83 }
无slack超时版
 1 #include <bits/stdc++.h>
 2 using namespace  std;
 3 const double inf=1e20;
 4 const int maxv=210;
 5 int n;
 6 struct node
 7 {
 8     int x,y;
 9 }a[maxv],b[maxv];
10 
11 double c[maxv][maxv];
12 double eg[maxv],eb[maxv];
13 int vb[maxv],vg[maxv];
14 int mc[maxv];
15 double slack[maxv];
16 
17 bool eq(double x,double y)
18 {
19     return fabs(x-y)<1e-10;
20 }
21 
22 int dfs(int x)
23 {
24     vg[x]=1;
25     for(int i=0;i<n;i++)
26     {
27         if(vb[i]) continue;
28         if(eq(eg[x]+eb[i],c[x][i]))
29         {
30             vb[i]=1;
31             if(mc[i]==-1||dfs(mc[i]))
32             {
33                 mc[i]=x;
34                 return 1;
35             }
36         }
37         else slack[i]=min(slack[i],eg[x]+eb[i]-c[x][i]);
38     }
39     return 0;
40 }
41 void KM()
42 {
43     memset(mc,-1,sizeof(mc));
44     memset(eb,0,sizeof(eb));
45     for(int i=0;i<n;i++)
46     {
47         eg[i]=c[i][0];
48         for(int j=1;j<n;j++)
49             eg[i]=max(eg[i],c[i][j]);
50     }
51     for(int i=0;i<n;i++)
52     {
53         for(int i=0;i<n;i++) slack[i]=inf;
54         while(1)
55         {
56             memset(vb,0,sizeof(vb));
57             memset(vg,0,sizeof(vg));
58             if(dfs(i)) break;
59             double d=1e20;
60             for(int i=0;i<n;i++) if(!vb[i]) d=min(d,slack[i]);
61             for(int i=0;i<n;i++)
62             {
63                 if(vg[i]) eg[i]-=d;
64                 if(vb[i]) eb[i]+=d;
65                 else slack[i]-=d;
66             }
67         }
68     }
69 }
70 
71 int main()
72 {
73     while(scanf("%d",&n)!=EOF&&n)
74     {
75         for(int i=0;i<n;i++) scanf("%d%d",&b[i].x,&b[i].y);
76         for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
77         for(int i=0;i<n;i++)
78             for(int j=0;j<n;j++)
79         {
80             double x=a[i].x-b[j].x;
81             double y=a[i].y-b[j].y;
82             c[i][j]=-sqrt(x*x+y*y);
83         }
84         KM();
85         for(int i=0;i<n;i++)
86             printf("%d\n",mc[i]+1);
87     }
88 }
View Code

 

Golden Tiger Claw

 UVA - 11383 

KM算法的副产品

KM之后,所有顶标之和是最小的

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define CLR(m,a) memset(m,a,sizeof(m))
 4 const int inf=0x3f3f3f3f;
 5 const int maxv=510;
 6 int n;
 7 int vb[maxv],vg[maxv],eb[maxv],eg[maxv];
 8 int mc[maxv];
 9 int slack[maxv];
10 int c[maxv][maxv];
11 
12 int dfs(int x)
13 {
14     vg[x]=1;
15     for(int i=0;i<n;i++)
16     {
17         if(vb[i]) continue;
18         int gap=eg[x]+eb[i]-c[x][i];
19         if(gap==0)
20         {
21             vb[i]=1;
22             if(mc[i]==-1||dfs(mc[i]))
23             {
24                 mc[i]=x;
25                 return 1;
26             }
27         }
28         else slack[i]=min(slack[i],gap);
29     }
30     return 0;
31 }
32 
33 void KM()
34 {
35     CLR(mc,-1);
36     CLR(eb,0);
37     for(int i=0;i<n;i++)
38     {
39         eg[i]=c[i][0];
40         for(int j=1;j<n;j++)
41             eg[i]=max(eg[i],c[i][j]);
42     }
43     for(int i=0;i<n;i++)
44     {
45         CLR(slack,inf);
46         while(1)
47         {
48             CLR(vb,0);
49             CLR(vg,0);
50             if(dfs(i)) break;
51             int d=inf;
52             for(int i=0;i<n;i++) if(!vb[i]) d=min(d,slack[i]);
53             for(int i=0;i<n;i++)
54             {
55                 if(vg[i]) eg[i]-=d;
56                 if(vb[i]) eb[i]+=d;
57             }
58         }
59     }
60 }
61 int main()
62 {
63     while(scanf("%d",&n)!=EOF)
64     {
65         for(int i=0;i<n;i++)
66             for(int j=0;j<n;j++)
67                 scanf("%d",&c[i][j]);
68         KM();
69         int ans=0;
70         for(int i=0;i<n;i++)
71             ans+=eg[i]+eb[i];
72         for(int i=0;i<n-1;i++)
73             printf("%d ",eg[i]);
74         printf("%d\n",eg[n-1]);
75         for(int i=0;i<n-1;i++)
76             printf("%d ",eb[i]);
77         printf("%d\n",eb[n-1]);
78         printf("%d\n",ans);
79     }
80 
81 }
View Code

 

posted @ 2017-07-24 10:51  yijiull  阅读(323)  评论(0编辑  收藏  举报