题意:从1到n 再从n到1 不经过重复的边 ,(如果是点就是旅行商问题了),问最短路
建立一个超级源S S到1连一条费用为0,容量为2的边,求费用流即可
如果流<2 那么hehe
否则 输出结果
模板来自Kuangbing 如下:
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #include <queue> #define oo 0x13131313 using namespace std; const int MAXN=200; const int MAXM=200000; const int INF=0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; void get(int a,int b,int c,int d) { to=a,cap=b,cost=c;next=d;flow=0; } }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N; void init(int n) { N=n; tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].get(v,cap,cost,head[u]);head[u]=tol++; edge[tol].get(u,0,-cost,head[v]);head[v]=tol++; } bool spfa(int s,int t) { queue<int>q; for(int i=0;i<N;i++) { dis[i]=INF; vis[i]=false; pre[i]=-1; } dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for(int i= head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(edge[i].cap>edge[i].flow&& dis[v]>dis[u]+edge[i].cost ) { dis[v]=dis[u]+edge[i].cost; pre[v]=i; if(!vis[v]) { vis[v]=true; q.push(v); } } } } if(pre[t]==-1) return false; else return true; } int minCostMaxflow(int s,int t,int &cost) { int flow=0; cost = 0; while(spfa(s,t)) { int Min=INF; for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) { if(Min >edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; } for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } flow+=Min; } return flow; } int main() { }完整代码如下:
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #include <queue> #define oo 0x13131313 using namespace std; const int MAXN=200; const int MAXM=200000; const int INF=0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; void get(int a,int b,int c,int d) { to=a,cap=b,cost=c;next=d;flow=0; } }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N; void init(int n) { N=n; tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].get(v,cap,cost,head[u]);head[u]=tol++; edge[tol].get(u,0,-cost,head[v]);head[v]=tol++; } bool spfa(int s,int t) { queue<int>q; for(int i=0;i<=N;i++) { dis[i]=INF; vis[i]=false; pre[i]=-1; } dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for(int i= head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(edge[i].cap>edge[i].flow&& dis[v]>dis[u]+edge[i].cost ) { dis[v]=dis[u]+edge[i].cost; pre[v]=i; if(!vis[v]) { vis[v]=true; q.push(v); } } } } if(pre[t]==-1) return false; else return true; } int minCostMaxflow(int s,int t,int &cost) { int flow=0; cost = 0; while(spfa(s,t)) { int Min=INF; for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) { if(Min >edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; } for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } flow+=Min; } return flow; } int NN,MM; void input() { int a,b,c; for(int i=1;i<=MM;i++) { scanf("%d%d%d",&a,&b,&c); addedge(a,b,1,c); addedge(b,a,1,c); } } void solve() { int ANS=0,t; addedge(NN+1,1,2,0); //建立源S=NN+1; t=minCostMaxflow(NN+1,NN,ANS); if(t==2) printf("%d\n",ANS); else printf("hehe\n"); } void File() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); } int main() { // File(); while(cin>>NN>>MM) { init(NN+1); input(); solve(); } }