最小流解法:先按照【上下界可行流】建图 但先不建end --> star 边
MAXFlow=按新建的源点和汇点跑一次最大流
再建end->star的边
MAXFlow+=再按新建的源点和汇点跑一次最大流
如果MAXFlow == 新建源点流出的sum值
则 有ans = end->star的流量
否则无ans
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <time.h>;
#define cler(arr, val) memset(arr, val, sizeof(arr))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
const int MAXN = 100;
const int MAXM = 1500;
const int INF = 0x3f3f3f3f;
//const int INF = 22222;
const int mod = 1000000007;
struct Edge
{
int to,next,cap,flow;
} edge[MAXM];
int tol,head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void init()
{
tol=0;
cler(head,-1);
}
void addedge(int u,int v,int w,int rw=0)
{
edge[tol].to=v,edge[tol].cap=w,edge[tol].flow=0,edge[tol].next=head[u];
head[u]=tol++;
edge[tol].to=u,edge[tol].cap=rw,edge[tol].flow=0,edge[tol].next=head[v];
head[v]=tol++;
}
int Q[MAXN];
void BFS(int star,int end)
{
cler(dep,-1);
cler(gap,0);
gap[0]=-1;
int front= 0, rear = 0;
dep[end]=0;
Q[rear++] = end;
while(front!= rear)
{
int u=Q[front++];
for(int i = head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].to;
if(dep[v]!= -1) continue;
Q[rear++]= v;
dep[v]=dep[u]+1;
gap[dep[v]]++;
}
}
}
int S[MAXN];
int sap(int star,int end,int N)
{
BFS(star,end);
memcpy(cur,head,sizeof(head));
int top=0, u=star,ans=0;
while(dep[star]<N)
{
if(u==end)
{
int Min=INF;
int inser;
for(int i=0; i<top; i++)
if(Min>edge[S[i]].cap-edge[S[i]].flow)
{
Min=edge[S[i]].cap-edge[S[i]].flow;
inser=i;
}
for(int i=0; i<top; i++)
{
edge[S[i]].flow+=Min;
edge[S[i]^1].flow-=Min;
}
ans+=Min;
top=inser;
u=edge[S[top]^1].to;
continue;
}
bool flag = false;
int v;
for(int i=cur[u]; i!=-1; i=edge[i].next)
{
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
{
flag = true;
cur[u]=i;
break;
}
}
if(flag)
{
S[top++] = cur[u];
u=v;
continue;
}
int Min=N;
for(int i= head[u]; i!=-1; i=edge[i].next)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
{
Min=dep[edge[i].to];
cur[u]=i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u]=Min+1;
gap[dep[u]]++;
if(u!=star) u=edge[S[--top]^1].to;
}
return ans;
}
char s[10];
int low[MAXN],star,end,sum;
int getnum(char *s)
{
if(strcmp(s,"+")==0) return star;
else if(strcmp(s,"-")==0) return end;
else return atoi(s);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
int n , m;
while(~scanf("%d%d",&n,&m),n+m)
{
cler(low,0);
init();
star=0,end=n+1,sum=0;
for(int i=0; i<m; i++)
{
int d;
char s1[5],s2[5];
scanf("%s %s %d",s1,s2,&d);
int l=getnum(s1),r=getnum(s2);
addedge(l,r,INF);
low[r]+=d;
low[l]-=d;
}
int Star=n+2,End=n+3;
for(int i=0;i<=n+1;i++)
{
if(low[i]>0)
{
addedge(Star,i,low[i]);
sum+=low[i];
}
else addedge(i,End,-low[i]);
}
int maxflow=sap(Star,End,n+4);
addedge(end,star,INF);
maxflow+=sap(Star,End,n+4);
if(maxflow!=sum)
printf("impossible\n");
else
printf("%d\n",edge[tol-2].flow);
}
return 0;
}