//此题主要是注意某些点虽然阔以一直不断追溯然后出环但是那个点不一定在环上。对于已经遍历过的点就不要重新遍历了,否则容易出现环数偏大然后导致streamint noot possible的情况
//对于这种经常涉及修改的题目函数设计的时候还是传参数比较好
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct edgee
{
int from, to, value,band;
edgee(int from, int to, int value, int band) :from(from), to(to), value(value), band(band)
{}
edgee()
{}
};
int pre[1000], visit[1000], minn[1000], belong[4000];
int n, m, cost, edgetot;
int root;
edgee edge[100000];
bool test(int pointtot,int band)
{
long long ans = 0;
while (1)
{
int circlenum = 0;
for (int i = 0; i < pointtot; i++)minn[i] = 1000000000, pre[i] = -1, belong[i] = -1, visit[i] = -1;
for (int i = 0; i < m; i++)
{
int from = edge[i].from, to = edge[i].to;
if (from != to&&edge[i].band >= band&&minn[to] > edge[i].value)
{
pre[to] = from; minn[to] = edge[i].value;
}
}
for (int i = 0; i < pointtot; i++)
{
if (i == root)continue;
if (minn[i] == 1000000000)return false;
}
for (int i = 0; i < pointtot; i++)
{
if (i != root)ans += minn[i];
if (i == root || visit[i] != -1)continue;
int temp = i;
while (temp != root&&visit[temp] == -1)
{
visit[temp] = i;
temp = pre[temp];
}
if (visit[temp] == i)
{
int q = temp;
while (pre[temp] != q)
{
belong[temp] = circlenum;
temp = pre[temp];
}
belong[temp] = circlenum;
circlenum++;
}
}
if (circlenum == 0)break;
for (int i = 0; i < pointtot; i++)if (belong[i] == -1)belong[i] = circlenum++;
for (int i = 0; i < edgetot; i++)
{
if (belong[edge[i].from] != belong[edge[i].to]) edge[i].value -= minn[edge[i].to];
edge[i].from = belong[edge[i].from];
edge[i].to = belong[edge[i].to];
}
pointtot = circlenum;
root = belong[root];
}
if (ans <= cost)
return true;
else
return false;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d", &n, &m, &cost);
edgetot = 0;
int l = 1000000000, r = -1;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d%d", &edge[edgetot].from, &edge[edgetot].to, &edge[edgetot].band, &edge[edgetot].value);
edge[i + m] = edge[i];
l = min(l, edge[edgetot].band); r = max(r, edge[edgetot].band);
edgetot++;
}
root = 0;
if (!test(n,l))
{
printf("streaming not possible.\n");
}
else
{
while (r > l)
{
int mid = l + (r - l + 1) / 2;
for (int i = 0; i < m; i++)edge[i] = edge[i + m];
root = 0;
if (test(n,mid))
l = mid;
else
r = mid - 1;
}
printf("%d kbps\n", l);
}
}
}
最小树形图uva11865
最新推荐文章于 2020-07-18 21:37:04 发布