Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

不需要卡精度

Posted by a6687543 at 2011-02-12 08:09:37 on Problem 3155
1、注意此题网络流中ans=n*m-c[s,t],因为c[s,t]是<=n*m,也就是说ans=f(g)>=0(此时|V|=0),那么f(g)不再单调递减,而是到了0后,一直为0。
2、可以证明,1/n^2的二分精度就可以了,
     设g为最优解,g1为其他解中任意一个,我们现在要证明【g-1/n^2,g】这个区间中的数(设为g2)对应的方案都是最优解的方案。
     由论文可得:g1<=g2<=g,此时最优解|E|-g2|V|>=0,其他解|E1|-g2|V1|<=0
     也就是说f(g2)所对应的最大方案仍旧是最优解,证毕。
附上我的代码:
//我同时乘上了n^2,变成了整型
# include<iostream>
using namespace std;
const int maxn=108,maxm=4008,oo=2147483647;
int a[maxm],next[maxm],start[maxn],tot,n,m,S,T,in[maxn],level[maxn],h[maxn],now[maxn],dfn[maxn];
int c[maxm];
struct arr
{
       int x,y;
}b[maxm];

void Init()
{
     scanf("%d%d",&n,&m);
     int i;
     for (i=1;i<=m;i++)
     {
         scanf("%d%d",&b[i].x,&b[i].y);
         in[b[i].x]++;in[b[i].y]++;
     }
     S=0;T=n+1;
}
void Add(int x,int y,int z,int t)
{
     a[++tot]=y;next[tot]=start[x];start[x]=tot;c[tot]=z;
     a[++tot]=x;next[tot]=start[y];start[y]=tot;if (t) c[tot]=z;else c[tot]=0;     
}
void Make_map(int g)
{
     memset(start,0,(T+1)<<2);tot=1;
     int i;
     for (i=1;i<=m;i++)  Add(b[i].x,b[i].y,n*n,1);
     for (i=1;i<=n;i++) {Add(S,i,m*n*n,0);Add(i,T,2*g+(m-in[i])*n*n,0);}
          
}
bool Bfs()
{
     int l=1,r=0;
     memset(level,0,(T+1)<<2);
     memcpy(now,start,(T+1)<<2);
     h[++r]=S;level[S]=1;
     while (l<=r)
     {
           int u=h[l];
           for (int i=start[u];i;i=next[i])
           {
               int v=a[i];
               if (c[i]&&level[v]==0)
               {
                  level[v]=level[u]+1;h[++r]=v;
                  if (v==T) return 1;
               }    
           }      
           ++l;
     }
     return 0;
}
int Dinic(int u,int l)
{
       if (u==T) return l;
       int t=l;
       for (now[u];now[u];now[u]=next[now[u]])
       {
           int i=now[u];
           int v=a[i];
           if (c[i]==0||level[v]!=level[u]+1) continue;
           int tmp=Dinic(v,min(c[i],l));
           c[i]-=tmp;c[i^1]+=tmp;l-=tmp;
           if (l==0) break;
       }    
       if (t==l) level[u]=-1;
       return t-l;
}
int F(int g)
{
     Make_map(g);
     int ans=0;
     while (Bfs()) ans+=Dinic(S,oo);
     return n*m*n*n-ans;
}
void Dfs(int u)
{
     dfn[u]=1;
     for (int i=start[u];i;i=next[i])
     {
         int v=a[i];
         if (c[i]&&dfn[v]==0) Dfs(v);    
     }     
}
void Work()
{
     int l=n,r=m*n*n;
     int ans=0;
     while (l<=r)
     {
           int mid=l+r>>1;
           int k=F(mid);
           if (k>0) {ans=max(mid,ans);l=mid+1;}else r=mid-1;
     }
     if (m==0) printf("%d\n%d\n",1,1);
     else
     {
         F(ans);
         memset(dfn,0,(T+1)<<2);
         Dfs(S);tot=0;
         for (int i=1;i<=n;i++) if (dfn[i]) tot++;
         printf("%d\n",tot);
         for (int i=1;i<=n;i++) if (dfn[i]) printf("%d\n",i);
     }
}
int main()
{
    Init();
    Work();
    return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator