- O(n3)
- 图不断在构造,判自环不能省。
- 无定根时设虚根,虚根向所有点连0。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn =70,maxm = 200005;
const int inf = 1e9;
int n,m,t,C,in[maxn],cnt,pre[maxn],id[maxn],vis[maxn];
struct edge
{
int u,v,w,c;
} e[maxm];
edge ee[maxm];
inline void add(int u,int v,int w,int c)
{
e[++cnt].v=v;
e[cnt].u=u;
e[cnt].c=c;
e[cnt].w=w;
ee[cnt].v=v;
ee[cnt].u=u;
ee[cnt].w=w;
ee[cnt].c=c;
}
bool zhuliu(int mid)
{
int root = 0,ans = 0;
while(1)
{
for(int i=0; i<n; i++)
in[i] = inf;
for(int i=1; i<=m; i++)
{
int v=e[i].v,c=e[i].c,u=e[i].u,w=e[i].w;
if(e[i].w>=mid&&c<in[v]&&u!=v)
{
in[v] = c;
pre[v] = u;
}
}
for(int i=0; i<n; i++)
{
if(i!=root&&in[i]==inf)
return false;
}
int num = 0;
memset(id,-1,sizeof(id));
memset(vis,-1,sizeof(vis));
in[root] = 0;
for (int i = 0; i < n; i++)
{
ans += in[i];
int v = i;
while (vis[v] != i && id[v] == -1 && v != root)
{
vis[v] = i;
v = pre[v];
}
if (v != root && id[v] == -1)
{
for (int u = pre[v]; u != v; u = pre[u])
id[u] = num;
id[v] = num++;
}
}
if (num == 0) break;
if(ans>C) return false;
for (int i=0;i <n;i++)
if (id[i]==-1) id[i] = num++;
for (int i=1;i<=m;i++)
{
int v = e[i].v;
e[i].v = id[e[i].v];
e[i].u = id[e[i].u];
if (e[i].u != e[i].v)
e[i].c -= in[v];
}
n = num;
root = id[root];
}
return ans<=C?true:false;
}
void init()
{
for(int i=1;i<=m;i++)
{
e[i].v=ee[i].v;
e[i].u=ee[i].u;
e[i].w=ee[i].w;
e[i].c=ee[i].c;
}
}
int main()
{
cin>>t;
while(t--)
{
cnt = 0;
scanf("%d%d%d",&n,&m,&C);
int l=0,r=1e9,ans=0;
for(int i=1,u,v,w,c; i<=m; i++)
{
scanf("%d%d%d%d",&u,&v,&w,&c);
add(u,v,w,c);
}
int tmp = n;
if(!zhuliu(0))
{
cout<<"streaming not possible."<<endl;
continue;
}
while(l<=r)
{
init();
n=tmp;
int mid=(l+r)>>1;
if(zhuliu(mid))
l=mid+1,ans=mid;
else
r=mid-1;
}
cout<<ans<<" kbps"<<endl;
}
return 0;
}