//对与存在的边连容量为INF的边 然后dfs记录下源点和汇点分别经过的点即可
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<memory.h> using namespace std; const int N=502; const int M=5002; const int INF=1<<29; int t,n,m,tot; int gap[M],dis[M],pre[M],head[N],cur[N],vis[N]; int NE,NV,sink,source; struct Node { int c,pos,next; } E[M*4]; #define FF(i,NV) for(int i=0;i<NV;i++) int sap(int s,int t) { memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug =INF; gap[0] = NV; while(dis[s] < NV) { loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c && dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug =INF; } goto loop; } } if( (--gap[dis[u]]) == 0) break; int mindis = NV; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow; } void addEdge(int u,int v,int c ) { E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++; } void dfs(int u) { vis[u]=1; for(int i=head[u]; i!=-1; i=E[i].next) { int v=E[i].pos; if(!vis[v]&&E[i].c>0) { // vis[v]=1;//表示该点未满流 dfs(v); } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { int i,j,add,u,v; source=0,sink=n<<1|1,NE=0,NV=sink+1; memset(head,-1,sizeof(int)*(NV)); memset(vis,0,sizeof(int)*(NV)); for(i=1; i<=n; i++) { scanf("%d",&add); addEdge(i+n,sink,add); } for(i=1; i<=n; i++) { scanf("%d",&add); addEdge(source,i,add); } for(i=1; i<=m; i++) { scanf("%d%d",&u,&v); addEdge(u,v+n,INF); } int ans=sap(source,sink); printf("%d\n",ans); int size=0; dfs(0); for(i=1; i<=n; i++) { if(!vis[i]) size++; if(vis[n+i]) size++; } printf("%d\n",size); for(i=1; i<=n; i++) { if(!vis[i]) printf("%d -\n",i); if(vis[n+i])printf("%d +\n",i); } } return 0; }