08-25 USACO 4.1~4.2 搜尋,最大流,二分匹配

來源:互聯網
上載者:User

今天一天迷迷糊糊的就沒做什麼題...好在把最大流理解了,看了半天演算法導論把 最小割基本也看懂了,LRJ的書說的太簡潔了...

一晚上看一道最小割的題目(HDU2435),但是還是沒做出來,痛苦啊,智商不夠,還是先去USACO做點題,明天再繼續想吧..(好吧,已經12點了...)


USACO 4.1.2 Drainage Ditches (DP+數論)

給幾個固定長度,問不能組成的最長長度是多少,如果無限長或不存在輸出0.

最簡單的是不存在的情況,如果沒有1,則1不可能由其它的長度組成,但有了1,所有長度自然都可以組成了...所以當讀到1時結果必為0了.

根據數論的知識,這幾個數的公約數為gc,如果gc不等於1,那麼除了gc倍數以外的數,都不能被組成,簡單的例子就是偶數不可能組成奇數..這時結果也為0.

考慮了這兩種情況以後,剩下的情況都是有解了,但是這個背包最大是多少呢?不會超過最大數的平方的..然後直接DP就可以了.

/*ID: swm80232PROG:nuggets LANG: C++*/#include <cstdio>#include <string>#include <math.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int n,box[12],d[256*256];int gcd(int a,int b){return b==0?a:gcd(b,a%b);}void dp(){memset(d,0,sizeof d);d[0]=1;for(int i=1;i<=n;i++){for(int j=box[i];j<=256*256;j++){if(d[j-box[i]])d[j]=1;}}}int main(){    freopen("nuggets.in","r",stdin);    freopen("nuggets.out","w",stdout);scanf("%d",&n);int yes=1,isf=1,gc;for(int i=1;i<=n;i++){scanf("%d",&box[i]);//如果都不為1,那麼1一定不能買到..但只要有1,所有要求都能滿足 if(box[i]==1)yes=0;if(i==1)gc=box[1];else gc=gcd(gc,box[i]);}//如果最大公約數不為1,那麼不能整除最大公約數的數都取不到 if(gc!=1)yes=0;if(yes==0){printf("0\n");return 0;}dp(); for(int i=256*256-1;i>=1;i--){if(d[i]==0){printf("%d\n",i);break;}}    //system("pause");    return 0;}


USACO 4.1.3Fence Rails 搜尋+剪枝

N個長度不同的木板上剪出M個長度不同的木料..剪枝是一門藝術啊..

/*ID: swm80232PROG:fence8LANG: C++*/#include <cstdio>#include <string>#include <math.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int n,m,a[55],b[1058],c[55],sa[55],sb[1058],res=0,space;int dfs(int st,int pos){if(st==0)return 1;//到達最短的木棍 //剪枝2:如果剩餘空間不足夠放所有剩下的木棍 if(space<sb[st])return 0; for(int i=n;i>=pos;i--){if(c[i]>=b[st]){c[i]-=b[st];//剪枝3:如果剩餘空間連第一根都不能放了,這個木板就已經沒用了 if(c[i]<b[1])space-=a[i]; //剪枝4:如果兩根一樣長,在a上切[s],在b上切[s+1]和在a上切[s+1],b上切[s]是一樣的,所以不用往前搜了//r~1023 leng~128 所以會有很多長度相同的 if(b[st]==b[st+1]){if(dfs(st-1,i))return 1;}else{if(dfs(st-1,1))return 1;}//回溯 if(c[i]<b[1])space+=a[i]; c[i]+=b[st];}}return 0;}bool cmp(int a,int b){return a>b;}int main(){    freopen("fence8.in","r",stdin);    freopen("fence8.out","w",stdout);       int l=0,r,mid,maxa;    scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]>maxa)maxa=a[i];}scanf("%d",&m);r=m;//二分的右端點 for(int i=1;i<=m;i++){scanf("%d",&b[i]);//剪枝1:比最大的木料長的肯定不能放進去 if(b[i]>maxa)r--; }  sort(a+1,a+n+1);//木板從小到大 sort(b+1,b+m+1);//木料從小到大(放的時候從大到小放)sa[0]=sb[0]=0;for(int i=1;i<=n;i++)sa[i]=sa[i-1]+a[i];for(int i=1;i<=m;i++)sb[i]=sb[i-1]+b[i];//二分,每次選前mid小的木料while(l<=r){memcpy(c,a,sizeof a);mid=(l+r)/2;space=sa[n];if(dfs(mid,1))l=mid+1;else r=mid-1;} printf("%d\n",(l+r)/2);   //system("pause");    return 0;}

USACO 4.2.2 Drainage Ditches

最大流,兩點之間可能存在多條邊,加上去就可以了..EK演算法

/*ID: swm80232PROG:ditchLANG: C++*/#include <cstdio>#include <string>#include <math.h>#include <string.h>#include <stdlib.h>#include <queue>#include <iostream>#include <algorithm>using namespace std;const int MAXN=202;const int INF=1e8;int n,m,cap[MAXN][MAXN],si,ei,ci;int flow[MAXN][MAXN],a[MAXN],vis[MAXN],p[MAXN],f;void EK(){memset(flow,0,sizeof flow);queue<int> q;while(1){memset(a,0,sizeof a);memset(vis,0,sizeof vis);a[1]=INF;vis[1]=1;q.push(1);while(!q.empty()){int u=q.front();q.pop();for(int v=1;v<=m;v++){if(vis[v]==0&&cap[u][v]>flow[u][v]){p[v]=u;vis[v]=1;q.push(v);a[v]=min(a[u],cap[u][v]-flow[u][v]);}}} if(a[m]==0)break;for(int i=m;i!=1;i=p[i]){flow[p[i]][i]+=a[m];flow[i][p[i]]-=a[m];}f+=a[m];}}int main(){    freopen("ditch.in","r",stdin);    freopen("ditch.out","w",stdout);memset(cap,0,sizeof cap);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d%d%d",&si,&ei,&ci);cap[si][ei]+=ci;}f=0;EK();printf("%d\n",f);    //system("pause");    return 0;}

USACO 4.2.3 The Perfect Stall

二分匹配,以前寫過,一段時間不做就忘得差不多了..把二分匹配又複習了一遍

/*ID: swm80232PROG:stall4LANG: C++*/#include <cstdio>#include <string>#include <math.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int n,m,map[205][205],a,b,vis[205],match[205];int dfs(int p){for(int i=1;i<=m;i++){if(!vis[i]&&map[p][i]){vis[i]=1;if(match[i]==0||dfs(match[i])){match[i]=p;return 1;}}}return 0;}int solve(){memset(match,0,sizeof match);int r=0;for(int i=1;i<=n;i++){memset(vis,0,sizeof vis);if(dfs(i))r++;}return r;}int main(){    freopen("stall4.in","r",stdin);    freopen("stall4.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a);for(int j=1;j<=a;j++){scanf("%d",&b);map[i][b]=1;}}printf("%d\n",solve());    //system("pause");    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.