P1431 [Tyvj Jan]分配任务
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
随着tyvj发展越来越大,管理员的任务越来越重,如何合理的分配任务,成为了一个可研究的命题。Tyvj当前一共有M个需要做的任务,和N位 管理员。每一个管理员的上线时间并不是固定的,每一个人有d[i]单位的上线时间,每一位管理员一个单位的时间可以完成一个任务,且一个任务只能由一个管 理员来完成(如果更多的管理员参与进来,可能会造成混乱)。每一位管理员的能力有所不同,所以能完成的任务集合可能不相同。最终让所有未完成的任务数量最 少。
输入格式
输入文件第一有两个正整数,分别是N和M
下面面N行,每一行表示一位管理员的信息,第一个正整数为d[i],第二个正整数为tot,后面有tot个数,表示第i位管理员可以完成的任务集合。
下面面N行,每一行表示一位管理员的信息,第一个正整数为d[i],第二个正整数为tot,后面有tot个数,表示第i位管理员可以完成的任务集合。
输出格式
输出文件仅有一个数,所有未完成任务的最少值。
测试样例1
输入
3 3
2 2 1 2
0 3 1 2 3
1 1 2
输出
1
备注
数据范围约定:
20%的数据 n<=10 M<=10 且D[i]=1
60%的数据 n<=50 M<=300 且D[i]<=30
100%的数据 n<=3000 M<=10000 且d[i]<=100
admin TYVJ首届月赛第三道
20%的数据 n<=10 M<=10 且D[i]=1
60%的数据 n<=50 M<=300 且D[i]<=30
100%的数据 n<=3000 M<=10000 且d[i]<=100
admin TYVJ首届月赛第三道
【思路】
最大流。裸题。
Dinic算法的时间复杂度为O(nm)。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 #define FOR(a,b,c) for(int a=(b);a<(c);a++) 6 using namespace std; 7 8 const int maxn = 15000+10; 9 const int INF = 1e9; 10 11 struct Edge{ 12 int u,v,cap,flow; 13 }; 14 struct Dinic { 15 int n,m,s,t; 16 bool vis[maxn]; 17 int d[maxn],cur[maxn]; 18 vector<int> G[maxn]; 19 vector<Edge> es; 20 21 void init(int n) { 22 this->n=n; 23 es.clear(); 24 for(int i=0;i<n;i++) G[i].clear(); 25 } 26 void AddEdge(int u,int v,int cap) { 27 es.push_back((Edge){u,v,cap,0}); 28 es.push_back((Edge){v,u,0,0}); 29 m=es.size(); 30 G[u].push_back(m-2); 31 G[v].push_back(m-1); 32 } 33 34 bool BFS() { 35 queue<int> q; 36 memset(vis,0,sizeof(vis)); 37 q.push(s); vis[s]=1; d[s]=0; 38 while(!q.empty()) { 39 int u=q.front(); q.pop(); 40 for(int i=0;i<G[u].size();i++) { 41 Edge& e=es[G[u][i]]; 42 int v=e.v; 43 if(!vis[v] && e.cap>e.flow) { 44 vis[v]=1; 45 d[v]=d[u]+1; 46 q.push(v); 47 } 48 } 49 } 50 return vis[t]; 51 } 52 int DFS(int u,int a) { 53 if(u==t || a==0) return a; 54 int flow=0,f; 55 for(int& i=cur[u];i<G[u].size();i++){ 56 Edge& e=es[G[u][i]]; 57 int v=e.v; 58 if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) { 59 e.flow+=f; 60 es[G[u][i]^1].flow-=f; 61 flow+=f,a-=f; 62 if(!a) break; 63 } 64 } 65 return flow; 66 } 67 int Maxflow(int s,int t) { 68 this->s=s , this->t=t; 69 int flow=0; 70 while(BFS()) { 71 memset(cur,0,sizeof(cur)); 72 flow+=DFS(s,INF); 73 } 74 return flow; 75 } 76 } dc; 77 78 int n,m; 79 80 int main() { 81 scanf("%d%d",&n,&m); 82 dc.init(n+m+2); 83 int s=n+m,t=s+1; 84 int x,a,b; 85 FOR(i,0,n) { 86 scanf("%d",&x); 87 dc.AddEdge(s,i,x); 88 scanf("%d",&a); 89 while(a--) { 90 scanf("%d",&b); b--; 91 dc.AddEdge(i,n+b,1); 92 } 93 } 94 FOR(i,0,m) dc.AddEdge(n+i,t,1); 95 int flow=dc.Maxflow(s,t); 96 printf("%d ",m-flow); 97 return 0; 98 }