题目描述
你的任务是制定出一个产品的分配方案,使得订单条件被满足,并且所有员工的愤怒值之和最小。由于我们并不想使用Special Judge,也为了使选手有更多的时间研究其他两道题目,你只需要输出最小的愤怒值之和就可以了。
输入输出格式
输入格式:
输出格式:
仅输出一个整数,表示最小的愤怒值之和。
输入输出样例
输入样例#1:
2 3 2 2 2 1 1 0 0 0 1 1 2 1 10 1 2 1 6
输出样例#1:
24
说明
一看,哇,修车,美食节,直接拆点,跑费用流,光荣T掉,还WA了几个点(原因不明)
然而这个题和修车不一样,每一份流量的性质都是相同的,没有拆点的必要,直接拆边就好了
SS--(C[i],0)-->物品i--(INF,0)-->员工j---(S[j][k]-s[j][k-1],W[i][j])-->TT
把每个员工到TT的边拆成S[i]+1条即可
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs ",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d ",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 100010; 31 const int MAXNODE = 700; 32 const int MAXEDGE = 1000000; 33 char BUF,*buf; 34 int read(){ 35 char c=getchar();int f=1,x=0; 36 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 37 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 38 return f*x; 39 } 40 char get_ch(){ 41 char c=getchar(); 42 while(!isalpha(c)) c=getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 int cnt,dis[MAXNODE],q[MAXNODE*MAXNODE],inq[MAXNODE],n,m,C[300],ok[300][300],S[300],T[300][7],W[300][7],SS,TT; 47 struct edge{ 48 int u,v,c,cost; 49 edge *nxt; 50 edge(){} 51 edge(int _u,int _v,int _c,int _cost,edge *_nxt):u(_u),v(_v),c(_c),cost(_cost),nxt(_nxt){} 52 }mp[MAXEDGE],*head[MAXNODE],*from[MAXNODE]; 53 void addedge(int u,int v,int c,int cost){ 54 mp[cnt]=edge(u,v,c,cost,head[u]); 55 head[u]=&mp[cnt++]; 56 mp[cnt]=edge(v,u,0,-cost,head[v]); 57 head[v]=&mp[cnt++]; 58 } 59 int spfa(int ss,int tt){ 60 memset(dis,INF,sizeof(dis)); 61 dis[ss]=0; 62 int *h,*t; 63 h=t=q; 64 *t++=ss; 65 while(h!=t){ 66 int p=*h++; 67 inq[p]=0; 68 iter(i,p){ 69 if(i->c&&dis[i->v]>dis[p]+i->cost){ 70 dis[i->v] = dis[p]+i->cost; 71 from[i->v]=i; 72 if(!inq[i->v]){ 73 *t++=i->v; 74 inq[i->v]=1; 75 } 76 } 77 } 78 } 79 return dis[tt]!=INF; 80 } 81 edge *rev(edge *e){ 82 return &mp[(e-mp)^1]; 83 } 84 ll extend(int ss,int tt){ 85 ll c=INF,cost=0; 86 int p=tt; 87 while(p!=ss){ 88 c=min(c,from[p]->c); 89 cost+=from[p]->cost; 90 p=from[p]->u; 91 } 92 p=tt; 93 while(p!=ss){ 94 from[p]->c-=c; 95 rev(from[p])->c+=c; 96 p=from[p]->u; 97 } 98 return c*cost; 99 } 100 ll cost_flow(int ss,int tt){ 101 ll ans=0; 102 while(spfa(ss,tt)){ 103 ans+=extend(ss,tt); 104 } 105 return ans; 106 } 107 void get_input(); 108 void work(); 109 int main() { 110 get_input(); 111 work(); 112 return 0; 113 } 114 void work(){ 115 SS=698;TT=699; 116 rep0(i,n){ 117 addedge(SS,i,C[i],0); 118 rep0(j,m) if(ok[j][i]) addedge(i,n+j,INF,0); 119 } 120 rep0(i,m){ 121 if(S[i]==0){ 122 addedge(n+i,TT,INF,W[i][0]); 123 }else{ 124 addedge(n+i,TT,T[i][0],W[i][0]); 125 for(int j=1;j<S[i];j++){ 126 addedge(n+i,TT,T[i][j]-T[i][j-1],W[i][j]); 127 } 128 addedge(n+i,TT,INF,W[i][S[i]]); 129 } 130 } 131 printf("%lld ",cost_flow(SS,TT)); 132 } 133 void get_input(){ 134 m=read();n=read(); 135 rep0(i,n) C[i]=read(); 136 rep0(i,m) rep0(j,n) ok[i][j]=read(); 137 rep0(i,m){ 138 S[i]=read(); 139 rep0(j,S[i]) T[i][j]=read(); 140 rep0(j,S[i]+1) W[i][j]=read(); 141 } 142 } 143 /* 144 2 3 145 2 2 2 146 1 1 0 147 0 0 1 148 1 149 2 150 1 10 151 1 152 2 153 1 6 154 */