想看更多的解題報告:http://blog.csdn.net/wangjian8006/article/details/7870410
轉載請註明出處:http://blog.csdn.net/wangjian8006
題目大意:愛麗絲要拍電影,有n部電影,規定愛麗絲每部電影在每個禮拜只有固定的幾天可以拍電影,只可以拍前面w個禮拜,並且這部電影要拍d天,問愛麗絲能不能拍完所有的電影
第一行代表有多少組資料
對於每組資料第一行代表有n部電影
接下來2到n+1行,每行代表一個電影,每行9個數,前面7個數,1代表拍,0代表不拍,第8個數代表要拍幾天,第9個數代表有幾個禮拜時間拍
解題思路:
這題可以看做成二分圖多重匹配,也可以用網路流實現,主要是建圖,將圖建好了就好說了
用s=0表示源點,t=371表示匯點
將371看做匯點的原因是,1-350表示每天,因為最多有50個星期....
351-370表示電影,因為電影最多隻有20部
源點指向每部電影,最大容量為這部電影所拍攝的天數
電影指向天數,因為每天只能拍一部電影,若這天可以拍這部電影就表示最大容量為1
天數都指向匯點,最大容量都為1
這樣建好圖之後就可以直接從源點到匯點求最大流,看最大流是否等於每個電影天數相加只和,相等則可以拍完,不等則拍不完
/*Memory 708KTime 47MS*/#include <iostream>#include <queue>using namespace std;#define min(a,b) (a>b?b:a)#define MAXV 372#define MAXINT INT_MAXint rc[MAXV][10];//1到7為星期幾,8是拍攝幾天,9是在多少周內完成int r[372][372];//容量int s,t,n,max_flow;//表示s源點與t匯點,n部電影int parent[MAXV];int dis[MAXV];void read_graph(){int i,j,k;for(i=1;i<=n;i++){r[0][i+350]=rc[i][8];for(j=1;j<=7;j++){if(rc[i][j]){for(k=0;k<rc[i][9];k++)r[i+350][j+k*7]=1;}}}for(i=1;i<=350;i++)r[i][371]=1;}int bfs(){int k;queue<int> q; memset(dis,-1,sizeof(dis)); dis[t]=0; q.push(t); while(!q.empty()){k=q.front();q.pop(); for(int i=0;i<372;i++){ if(dis[i]==-1 && r[i][k]){ dis[i]=dis[k]+1; q.push(i); } } if(k==s) return 1; }return 0;}int dfs(int cur,int cp){ if(cur==t)return cp; int tmp=cp,t; for(int i=0;i<372 && tmp;i++){ if(dis[i]+1==dis[cur] && r[cur][i]){ t=dfs(i,min(r[cur][i],tmp)); r[cur][i]-=t; r[i][cur]+=t; tmp-=t; } } return cp-tmp;}void dinic(){ max_flow=0; while(bfs()){max_flow+=dfs(s,MAXINT); }}int main(){int i,j,ans,cnt;scanf("%d",&cnt);while(cnt--){ans=0;s=0;t=371;memset(r,0,sizeof(r));scanf("%d",&n);for(i=1;i<=n;i++){for(j=1;j<=9;j++)scanf("%d",&rc[i][j]);ans+=rc[i][8];}read_graph();//建圖dinic();if(ans==max_flow) printf("Yes\n");else printf("No\n");}return 0;}