| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
带需求的可行流问题 可以转化为最大流//但是老RE没法了!
#include <iostream>
using namespace std;
const int MAXN = 205;//点的标号[0..MAXN-1]
const int MAXM2 = 5005*2;
const int INF = (1<<20);
struct Edge
{
int st, ed;
int next;
int flow;//边的剩余容量
}edge[MAXM2];//残留网络
//head 链接表的头结点
int head[MAXN];
int E, src, dest;
void Init(int s, int t)//先初始化,后读入图
{
E = 0;
src = s;
dest = t;
memset(head, -1, sizeof(head));
}
void add_edge(int u, int v, int w)//u-->v:w
{ //允许任意形状的网络
edge[E].st = u; edge[E].ed = v;
edge[E].flow = w; edge[E].next = head[u];
head[u] = E++;
edge[E].st = v; edge[E].ed = u;
edge[E].flow = 0; edge[E].next = head[v];
head[v] = E++;
}
//////////////////////dinic
int d[MAXN],que[MAXN],stk[MAXN],edgptr[MAXN];
bool dinic_bfs()
{
int i, j ,rear=1;
memset(d, -1, sizeof(d));
que[0] = src; d[src] = 0;
for(i = 0; i < rear; i++)
for(j = head[que[i]]; j != -1; j = edge[j].next)
if(d[edge[j].ed] == -1 && edge[j].flow > 0)
{
d[edge[j].ed] = d[que[i]]+1;
que[rear++] = edge[j].ed;
}
return d[dest] >= 0;
}
int dinic_dfs()
{
int ans = 0, top =0 ,cur, ptr, minf, i,pose;
stk[top++] = src;
while(top)
{
for(cur=stk[top-1],i = head[cur]; i != -1; i = edge[i].next)
{
if(d[edge[i].ed] == d[cur]+1 && edge[i].flow > 0 )
{
stk[top++] = edge[i].ed;
cur=edge[i].ed;
edgptr[cur] = i;
break;
}
}
if(i == -1)
{
d[cur] = 0; //删点
--top;
continue;
}
//update the flow
if(cur == dest)
{
minf = INF;
while(cur != src) //必须到达后才开始找minf
{
ptr = edgptr[cur];
if(edge[ptr].flow < minf) minf = edge[ptr].flow;
cur = edge[ptr].st;
}
cur = dest;
while(cur != src)
{
ptr = edgptr[cur];
edge[ptr].flow -= minf;
edge[ptr^1].flow += minf;
if(edge[ptr].flow == 0) pose = edge[ptr].st;
cur = edge[ptr].st;
}
while(top > 0 && stk[top-1] != pose) top--;
ans += minf;
}
}
return ans;
}
int Dinic()
{
int ans = 0, t;
while(dinic_bfs())
{
t = dinic_dfs();
if(t) ans += t;
else break;
}
return ans;
}
////////////////////////////////////////////////高效ac了n多题
//dicnic后dfs(s)即可求的最小割集
int need[MAXN];
int deg[MAXN];
int main()
{
int t,n,m,s,f;
cin>>t;
while(t--)
{
memset(need,0,sizeof(need));
memset(deg,0,sizeof(deg));
cin>>n>>m;
Init(0,n+1);
while(m--)
{
cin>>s>>t>>f;
deg[s]++;deg[t]++;
if(s==t)continue;
if(f==1)
{
need[s]--;
need[t]++;
}
else
{
add_edge(s,t,1);
add_edge(t,s,1);
}
}
for(f=1;f<=n;++f)if(deg[f]%2==1)break;
if(f<=n)
{
cout<<"impossible\n";
continue;
}
int needsum=0;
for(f=1;f<=n;++f)
{
if(need[f]<0)add_edge(f,dest,-need[f]);
if(need[f]>0){add_edge(src,f,need[f]);needsum+=need[f];}
}
int ans=Dinic();
if(ans==needsum)cout<<"possible\n";
else cout<<"impossible\n";
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator