谁会像我一样把INF设成0x3f?
GH Tree.
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 250 #define maxe 50050 #define inf 0x7fffffff using namespace std; struct edge { int v,f,nxt; }e[maxe]; int T,a,b,c,qq; int n,m,map[maxv][maxv],f[maxv][maxv],s,t,nume,g[maxv]; int regis[maxv*maxv],cnt=0; int dis[maxv],fath[maxv],rrr=0; bool vis[maxv]; queue <int> q; void reset() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { map[i][j]=0; f[i][j]=inf; } } void addedge(int u,int v,int w) { e[++nume].v=v; e[nume].nxt=g[u]; e[nume].f=w; g[u]=nume; e[++nume].v=u; e[nume].f=0; e[nume].nxt=g[v]; g[v]=nume; } void build() { nume=1;memset(g,0,sizeof(g)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { if (map[i][j]) addedge(i,j,map[i][j]); } } bool bfs() { while (!q.empty()) q.pop(); memset(dis,0,sizeof(dis)); memset(vis,false,sizeof(vis)); vis[s]=true;q.push(s); while (!q.empty()) { int head=q.front(); q.pop(); for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f) && (!vis[v])) { dis[v]=dis[head]+1; vis[v]=true;q.push(v); } } } return dis[t]>0; } int dinic(int x,int low) { if (x==t) return low; else { int ret=0; for (int i=g[x];low && i;i=e[i].nxt) { int v=e[i].v; if ((dis[v]==dis[x]+1) && (e[i].f)) { int dd=dinic(v,min(low,e[i].f)); e[i].f-=dd;e[i^1].f+=dd; low-=dd;ret+=dd; } } if (!ret) dis[x]=0; return ret; } } int max_flow(int x,int y) { s=x;t=y; int ans=0; while (bfs()) ans+=dinic(s,inf); return ans; } void dfs(int x) { vis[x]=true; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if ((!vis[v]) && (e[i].f)) dfs(v); } } void Gusfield() { for (int i=1;i<=n;i++) fath[i]=1; for (int i=2;i<=n;i++) { build(); int maxf=max_flow(fath[i],i); memset(vis,false,sizeof(vis)); dfs(fath[i]); for (int j=1;j<i;j++) f[i][j]=f[j][i]=min(f[j][fath[i]],maxf); for (int j=i+1;j<=n;j++) { if ((fath[i]==fath[j]) && (!vis[j])) fath[j]=i; } } } void get_ans() { cnt=0; for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) regis[++cnt]=f[i][j]; sort(regis+1,regis+cnt+1); scanf("%d",&qq); for (int i=1;i<=qq;i++) { int tot=0;scanf("%d",&a); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(f[i][j]<=a)tot++; printf("%d\n",tot); } printf("\n"); } void work() { scanf("%d%d",&n,&m); reset(); for (int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); map[a][b]+=c;map[b][a]+=c; } Gusfield(); get_ans(); } int main() { scanf("%d",&T); for (int i=1;i<=T;i++) work(); return 0; }
时间: 2024-10-27 00:37:16