bzoj2001: [Hnoi2010]City 城市建设 wikioi2332

两个关键的操作:
  Reduction(删除无用边):
  把待修改的边标为INF,做一遍MST,把做完后不在MST中的非INF边删去(因为这些边在原图的情况下肯定更不可能选进MST的边集,即无用边);
  Contraction(缩必须边):
  把待修改的边标为-INF,做一遍MST,在MST中的非-INF边为必须边(因为这些边在原图的情况下也一定会被选进MST),缩点。
/**************************************************************
    Problem: 2001
    User: xujiahe
    Language: C++
    Result: Accepted
    Time:4084 ms
    Memory:24656 kb
****************************************************************/
 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define maxn 51000
struct quest
{
    int x,y;
}q[60000];
struct node
{
    int pos,x,y,w;
}e[25][maxn],d[maxn],t[maxn];//e[][]用来记录分层图,d[]记录当前图,t[]可以当做中间变量。
int n,m,Q;
int father[maxn],val[maxn],c[maxn],size[maxn],sum[maxn];
long long ans[maxn];
inline bool cmp(node aa,node bb) { return aa.w>1;//对讯问进行分治
    sum[now+1]=tot;
    solve(l,mid,now+1,cnt);
    solve(mid+1,r,now+1,cnt);
}
int main()
{
    int x,y,z;
    scanf("%d%d%d",&n,&m,&Q);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&val[i]);
        e[0][i].x=x;//初始图的序号为0
        e[0][i].y=y;
        e[0][i].w=val[i];
        e[0][i].pos=i;//记录编号。
    }
    for(int i=1;i<=Q;i++)
    {
        scanf("%d%d",&q[i].x,&q[i].y);
    }
    sum[0]=m;//sum记录每个图有几条有用边
    solve(1,Q,0,0);//对讯问进行分治
    for(int i=1;i<=Q;i++)
    {
        printf("%lld\n",ans[i]);
    }
    return 0;
}

你可能感兴趣的:(codevs(wikioi),图论,bzoj,MST)