
3 3 4 1 2 5 2 1 2 2 3 10 3 1 7 3 2 1 2 3 1 2 4 2 2 1 2 3 1 2 4
Case 1: 19 Case 2: NO Case 3: 6HintIn Case 1: You could delete edge between 1 and 2 whose weight is 5. In Case 2: It’s impossible to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation.
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int MAXN = 10010;
const int MAXM = 100100;
const int INF = 1<<30;
struct EDG{
int to,next,cap,flow;
int cost; //每条边的单价
}edg[MAXM];
int head[MAXN],eid;
int pre[MAXN], cost[MAXN] ; //点0~(n-1)
void init(){
eid=0;
memset(head,-1,sizeof(head));
}
void addEdg(int u,int v,int cap,int cst){
edg[eid].to=v; edg[eid].next=head[u]; edg[eid].cost = cst;
edg[eid].cap=cap; edg[eid].flow=0; head[u]=eid++;
edg[eid].to=u; edg[eid].next=head[v]; edg[eid].cost = -cst;
edg[eid].cap=0; edg[eid].flow=0; head[v]=eid++;
}
bool inq[MAXN];
bool spfa(int sNode,int eNode,int n){
queue<int>q;
for(int i=0; i<n; i++){
inq[i]=false; cost[i]= INF;
}
cost[sNode]=0; inq[sNode]=1; pre[sNode]=-1;
q.push(sNode);
while(!q.empty()){
int u=q.front(); q.pop();
inq[u]=0;
for(int i=head[u]; i!=-1; i=edg[i].next){
int v=edg[i].to;
if(edg[i].cap-edg[i].flow>0 && cost[v]>cost[u]+edg[i].cost){ //在满足可增流的情况下,最小花费
cost[v] = cost[u]+edg[i].cost;
pre[v]=i; //记录路径上的边
if(!inq[v])
q.push(v),inq[v]=1;
}
}
}
return cost[eNode]!=INF; //判断有没有增广路
}
//反回的是最大流,最小花费为minCost
int minCost_maxFlow(int sNode,int eNode ,int& minCost,int n){
int ans=0;
while(spfa(sNode,eNode,n)){
ans++;
for(int i=pre[eNode]; i!=-1; i=pre[edg[i^1].to]){
edg[i].flow+=1; edg[i^1].flow-=1;
minCost+=edg[i].cost;
}
}
return ans;
}
void scanf(int &ans){
char ch;
while(ch=getchar()){
if(ch>='0'&&ch<='9')
break;
}
ans=ch-'0';
while(ch=getchar()){
if(ch<'0'||ch>'9')
break;
ans=ans*10+ch-'0';
}
}
int mapt[1005][1005];
int main(){
int T,_case=0,n,m , u, v, d ;
scanf(T);
while(T--){
scanf(n); scanf(m);
init();
int s=0, t=2*n+1;
for(int i=1; i<=n; i++){
addEdg(s , i , 1 , 0);
addEdg(i+n , t , 1 , 0);
for(int j=1; j<=n; j++)
mapt[i][j]=INF;
}
while(m--){
scanf(u); scanf(v); scanf(d);
if(mapt[u][v]>d)
mapt[u][v]=mapt[v][u]=d;
}
for( u=1; u<=n; u++)
for(v=1; v<=n; v++)
if(mapt[u][v]!=INF)
addEdg(u,v+n,1,mapt[u][v]);
int mincost=0;
n-= minCost_maxFlow(s , t , mincost , t+1);
printf("Case %d: ",++_case);
if(n==0)
printf("%d\n",mincost);
else
printf("NO\n");
}
}
HDU 3435 A new Graph Game(最小费用最大流)&HDU 3488
原文地址:http://blog.csdn.net/u010372095/article/details/46635847