思路:
这题考的是最大闭权图。只要知道怎么求最大闭权图就知道怎么做。但好像有点卡模版,要高效的模版才行。
#include#include #include #define Maxn 6010#define Maxm 200000#define LL __int64#define Abs(a) (a)>0?(a):(-a)using namespace std;struct Edge{ int from,to,next; LL val;}edge[Maxm];LL value[Maxn],inf=0;int index[Maxn],work[Maxn],dis[Maxn],q[Maxn],e,vi[Maxn];inline void addedge(int from,int to,LL val)//有向边{ edge[e].from=from; edge[e].to=to; edge[e].val=val; edge[e].next=index[from]; index[from]=e++; edge[e].from=to; edge[e].to=from; edge[e].val=0; edge[e].next=index[to]; index[to]=e++;}void init(){ e=0; memset(index,-1,sizeof(index)); memset(vi,0,sizeof(vi)); inf=0;}void add(int u,int v,LL c){ edge[e].to=v;edge[e].val=c;edge[e].next=index[u];index[u]=e++; edge[e].to=u;edge[e].val=0;edge[e].next=index[v];index[v]=e++;}void DFS(int u){ vi[u]=1; int i,v; for(i=index[u];i!=-1;i=edge[i].next) if(edge[i].val&&!vi[edge[i].to]) DFS(edge[i].to);}int bfs(int S,int T){ int rear=0; memset(dis,-1,sizeof(dis)); dis[S]=0;q[rear++]=S; for(int i=0;i 0) { sum+=value[i]; addedge(0,i,value[i]); } else addedge(i,n+1,-value[i]); inf+=Abs(value[i]); } inf++; for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); addedge(a,b,inf); } LL ans=Dinic(0,n+1);//起始点和结束点 //DFS(0);//寻找S集合 int num=0; for(i=1;i<=n;i++) if(dis[i]>=0) num++; printf("%d %I64d\n",num,sum-ans); return 0;}