HDU 3572 Task Schedule
2012-08-14 19:09 javaspring 阅读(231) 评论(0) 编辑 收藏 举报这个题目,纠结 了很久! 到现在还不知道自己的代码哪里RE了! 先保存下,慢慢再看吧。。
我的:
#include<iostream> #include<algorithm> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<queue> #include<math.h> #define MAXN 1210 #define INF 1<<30 using namespace std; struct set { int u,v,w,next; }edge[503000]; int idx,n,m,s,t; int fa[MAXN],res[MAXN],level[MAXN],gap[MAXN],head[MAXN],cur[MAXN]; int MIN(int a,int b){return a<b?a:b;} void addedge(int u,int v,int w) { edge[idx].u=u; edge[idx].v=v; edge[idx].w=w; edge[idx].next=head[u]; head[u]=idx++; edge[idx].u=v; edge[idx].v=u; edge[idx].w=0; edge[idx].next=head[v]; head[v]=idx++; } int retreat(int u) { int id,v,min_level=t+1; cur[u]=head[u]; for(id=head[u];id!=-1;id=edge[id].next) { v=edge[id].v; if(edge[id].w>0 && level[v]<min_level) { min_level=level[v]; cur[u]=id; } } return min_level+1; } int sap() { int id,i,u=s,v,flow=0; memset(level,0,sizeof(level)); memset(gap,0,sizeof(gap)); res[s]=INF; fa[s]=-1; gap[0]=t+1; for(i=0;i<=t+1;i++) cur[i]=head[i]; while(level[s]<=t) { int fine=0; if(u==t) { flow+=1; for(i=fa[u];i!=-1;i=fa[i]) { id=cur[i]; edge[id].w-=1; edge[id ^1].w+=1; res[i]-=1; if(edge[id].w==0) u=i; } } for(id=cur[u];id!=-1;id=edge[id].next) { v=edge[id].v; if(edge[id].w>0 && level[u]==level[v]+1) { res[v]=MIN(res[u],edge[id].w); fa[v]=u; cur[u]=id; u=v; fine=1; break; } } if(!fine) { if(--gap[level[u]]==0) return flow; v=retreat(u); level[u]=v; gap[v]++; if(u!=s) u=fa[u]; } } return flow; } int main() { // freopen("in.txt","r",stdin); int i,j,test,a,x,b; scanf("%d",&test); for(int ca=1;ca<=test;ca++) { memset(head,-1,sizeof(head)); int idx=0,topx=0,maxb=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d%d%d",&x,&a,&b); if(b>maxb) maxb=b; topx+=x; addedge(0,i,x); for(j=n+a;j<=n+b;j++) addedge(i,j,1); } s=0; t=maxb+n+1; for(i=n+1;i<=n+maxb;i++) addedge(i,t,m); printf("Case %d: %s\n\n",ca,(sap()==topx)?"Yes":"No"); } return 0; }
能AC 的:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int maxn = 1111; const int maxm = 505000; const int oo = 1 << 30; int idx; int cur[maxn], pre[maxn]; int dis[maxn], gap[maxn]; int aug[maxn], head[maxn]; struct Node { int u, v, w; int next; }edge[maxm]; void addEdge(int u, int v, int w) { edge[idx].u = u; edge[idx].v = v; edge[idx].w = w; edge[idx].next = head[u]; head[u] = idx++; edge[idx].u = v; edge[idx].v = u; edge[idx].w = 0; edge[idx].next = head[v]; head[v] = idx++; } int SAP(int s, int e, int n) { int max_flow = 0, v, u = s; int id, mindis; aug[s] = oo; pre[s] = -1; memset(dis, 0, sizeof(dis)); memset(gap, 0, sizeof(gap)); gap[0] = n; // 我觉得这一句要不要都行,因为dis[e]始终为0 for (int i = 0; i <= n; ++i) { // 初始化当前弧为第一条弧 cur[i] = head[i]; } while (dis[s] < n) { bool flag = false; if (u == e) { max_flow += aug[e]; for (v = pre[e]; v != -1; v = pre[v]) // 路径回溯更新残留网络 { id = cur[v]; edge[id].w -= aug[e]; edge[id^1].w += aug[e]; aug[v] -= aug[e]; // 修改可增广量,以后会用到 if (edge[id].w == 0) u = v; // 不回退到源点,仅回退到容量为0的弧的弧尾 } } for (id = cur[u]; id != -1; id = edge[id].next) { // 从当前弧开始查找允许弧 v = edge[id].v; if (edge[id].w > 0 && dis[u] == dis[v] + 1) // 找到允许弧 { flag = true; pre[v] = u; cur[u] = id; aug[v] = min(aug[u], edge[id].w); u = v; break; } } if (flag == false) { if (--gap[dis[u]] == 0) break; /* gap优化,层次树出现断层则结束算法 */ mindis = n; cur[u] = head[u]; for (id = head[u]; id != -1; id = edge[id].next) { v = edge[id].v; if (edge[id].w > 0 && dis[v] < mindis) { mindis = dis[v]; cur[u] = id; // 修改标号的同时修改当前弧 } } dis[u] = mindis + 1; gap[dis[u]]++; if (u != s) u = pre[u]; // 回溯继续寻找允许弧 } } return max_flow; } int main() { // freopen("in.txt","r",stdin); int t, n, m, pi, si, ei; int Max, sum, source, sink, vn; scanf("%d", &t); for (int cas = 1; cas <= t; ++cas) { idx = 0; memset(head, -1, sizeof(head)); sum = 0; source = 0; Max = 0; scanf("%d %d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d %d %d", &pi, &si, &ei); sum += pi; Max = max(Max, ei); addEdge(source, i, pi); for (int j = si; j <= ei; ++j) { addEdge(i, n + j, 1); } } sink = n + Max + 1; vn = sink + 1; for (int i = 1; i <= Max; ++i) { addEdge(n + i, sink, m); } if (SAP(source, sink, vn) == sum) printf("Case %d: Yes\n\n", cas); else printf("Case %d: No\n\n", cas); } return 0; }