/*我也沒有讀題 剛學就直接搜的這類題 找了個簡單的練習大致上好像是這麼個意思 給你一個圖 邊有上下界求無源匯最大流 沒有輸出NO 有則輸出 YES 並輸出 各邊的流量*/#include<iostream>#include<string.h>using namespace std;const int N=205;struct node{int u,v;}e[N*N];int l[N][N],u[N][N],g[N][N],d[N],num[N],n,m,sink,src;int min(int a,int b){return a<b?a:b;}int sap(int u,int f){if(u==sink) return f; int v,mind=n+1,last=f,cost; for(v=0;v<=n+1;++v) { if(g[u][v]>0)//有流量 { if(d[u]==d[v]+1)//有允許邊 { cost=sap(v,min(last,g[u][v])); g[u][v]-=cost;//修改圖 g[v][u]+=cost; last-=cost;//修改剩餘流量 if(d[src]>=n+2)//結束標誌 return f-last; if(last==0)//使用完就退出 break; } if(d[v]<mind)//下面更新距離的時候用 求其能串連到的最小距離 這個判斷和上邊的那個判斷並列 因為他們是互斥的,只有當找不到允許邊的時候才用得著mind mind=d[v]; } } if(last==f)//流量沒有使用 即 沒有允許邊 { --num[d[u]]; if(num[d[u]]==0)//若出現斷層 { d[src]=n+2; } d[u]=mind+1; ++num[d[u]]; } return f-last; }int main(){int t,i,j,a,b,c,h;cin>>t;while(t--){memset(g,0,sizeof(g));memset(l,0,sizeof(l));//曾經忘了初始化這倆 老是錯 memset(u,0,sizeof(u));//cin>>n>>m;sink=n+1;src=0;for(i=1;i<=m;++i){cin>>a>>b>>c>>h;e[i].u=a;//記錄邊 以便 存在答案是輸出用e[i].v=b;l[a][b]=c;u[a][b]=h;}b=0;for(i=1;i<=n;++i){a=0;for(j=1;j<=n;++j){a+=l[j][i]-l[i][j];//統計 輸入資料流比輸出資料流多多少 g[i][j]=u[i][j]-l[i][j];}if(a>0)b+=g[0][i]=a;else g[i][n+1]=-a;}c=0;memset(d,0,sizeof(d));memset(num,0,sizeof(num));for(num[0]=n+2;d[0]<n+2;)c+=sap(0,0x7fffffff);if(c<b)cout<<"NO"<<endl;else{cout<<"YES"<<endl;for(i=1;i<=m;++i)cout<<(u[e[i].u][e[i].v]-g[e[i].u][e[i].v])<<endl;}}return 0;}