标签:sam include gap tom save from ott amp href
http://acm.hdu.edu.cn/showproblem.php?pid=3599
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1870 Accepted Submission(s): 442
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<cstdio> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define INF 0x3f3f3f3f 11 #define maxn 2005 12 #define MAXN 1000005 13 #define mem(a,b) memset(a,b,sizeof(a)) 14 using namespace std; 15 16 int n; 17 struct sair{ 18 int len,pos; 19 bool operator<(const sair &b)const{ 20 return len>b.len; 21 } 22 }; 23 int dis[maxn]; 24 int vis[maxn]; 25 vector<pair<int,int> >ve[maxn]; 26 void Dijstra(){ 27 priority_queue<sair>q; 28 sair tmp; 29 tmp.len=0,tmp.pos=1; 30 dis[1]=0; 31 q.push(tmp); 32 while(!q.empty()){ 33 tmp=q.top(); 34 q.pop(); 35 int pos=tmp.pos; 36 if(vis[pos]){ 37 continue; 38 } 39 vis[pos]=1; 40 for(int i=0;i<ve[pos].size();i++){ 41 int f=ve[pos][i].first; 42 int len=ve[pos][i].second; 43 44 if(dis[f]>dis[pos]+len){ 45 dis[f]=dis[pos]+len; 46 tmp.pos=f; 47 tmp.len=dis[f]; 48 q.push(tmp); 49 } 50 } 51 } 52 } 53 54 struct Edge{ 55 int v,next; 56 int cap,flow; 57 }edge[MAXN*5];//注意这里要开的够大。。不然WA在这里真的想骂人。。问题是还不报RE。。 58 int cur[MAXN],pre[MAXN],gap[MAXN],path[MAXN],dep[MAXN]; 59 int cnt=0;//实际存储总边数 60 void isap_init() 61 { 62 cnt=0; 63 memset(pre,-1,sizeof(pre)); 64 } 65 void isap_add(int u,int v,int w)//加边 66 { 67 edge[cnt].v=v; 68 edge[cnt].cap=w; 69 edge[cnt].flow=0; 70 edge[cnt].next=pre[u]; 71 pre[u]=cnt++; 72 } 73 void add(int u,int v,int w){ 74 isap_add(u,v,w); 75 isap_add(v,u,0); 76 } 77 bool bfs(int s,int t)//其实这个bfs可以融合到下面的迭代里,但是好像是时间要长 78 { 79 memset(dep,-1,sizeof(dep)); 80 memset(gap,0,sizeof(gap)); 81 gap[0]=1; 82 dep[t]=0; 83 queue<int>q; 84 while(!q.empty()) q.pop(); 85 q.push(t);//从汇点开始反向建层次图 86 while(!q.empty()) 87 { 88 int u=q.front(); 89 q.pop(); 90 for(int i=pre[u];i!=-1;i=edge[i].next) 91 { 92 int v=edge[i].v; 93 if(dep[v]==-1&&edge[i^1].cap>edge[i^1].flow)//注意是从汇点反向bfs,但应该判断正向弧的余量 94 { 95 dep[v]=dep[u]+1; 96 gap[dep[v]]++; 97 q.push(v); 98 //if(v==sp)//感觉这两句优化加了一般没错,但是有的题可能会错,所以还是注释出来,到时候视情况而定 99 //break; 100 } 101 } 102 } 103 return dep[s]!=-1; 104 } 105 int isap(int s,int t) 106 { 107 if(!bfs(s,t)) 108 return 0; 109 memcpy(cur,pre,sizeof(pre)); 110 //for(int i=1;i<=n;i++) 111 //cout<<"cur "<<cur[i]<<endl; 112 int u=s; 113 path[u]=-1; 114 int ans=0; 115 while(dep[s]<n)//迭代寻找增广路,n为节点数 116 { 117 if(u==t) 118 { 119 int f=INF; 120 for(int i=path[u];i!=-1;i=path[edge[i^1].v])//修改找到的增广路 121 f=min(f,edge[i].cap-edge[i].flow); 122 for(int i=path[u];i!=-1;i=path[edge[i^1].v]) 123 { 124 edge[i].flow+=f; 125 edge[i^1].flow-=f; 126 } 127 ans+=f; 128 u=s; 129 continue; 130 } 131 bool flag=false; 132 int v; 133 for(int i=cur[u];i!=-1;i=edge[i].next) 134 { 135 v=edge[i].v; 136 if(dep[v]+1==dep[u]&&edge[i].cap-edge[i].flow) 137 { 138 cur[u]=path[v]=i;//当前弧优化 139 flag=true; 140 break; 141 } 142 } 143 if(flag) 144 { 145 u=v; 146 continue; 147 } 148 int x=n; 149 if(!(--gap[dep[u]]))return ans;//gap优化 150 for(int i=pre[u];i!=-1;i=edge[i].next) 151 { 152 if(edge[i].cap-edge[i].flow&&dep[edge[i].v]<x) 153 { 154 x=dep[edge[i].v]; 155 cur[u]=i;//常数优化 156 } 157 } 158 dep[u]=x+1; 159 gap[dep[u]]++; 160 if(u!=s)//当前点没有增广路则后退一个点 161 u=edge[path[u]^1].v; 162 } 163 return ans; 164 } 165 struct Bian{ 166 int x,y,v; 167 }B[MAXN]; 168 169 int main(){ 170 171 std::ios::sync_with_stdio(false); 172 int T; 173 cin>>T; 174 while(T--){ 175 cin>>n; 176 for(int i=0;i<=n;i++){ 177 dis[i]=INF; 178 vis[i]=0; 179 } 180 for(int i=0;i<=n;i++){ 181 ve[i].clear(); 182 } 183 int a,b,c; 184 int j; 185 int co=0; 186 while(cin>>B[co].x>>B[co].y>>B[co].v){ 187 if(!B[co].x&&!B[co].y&&!B[co].v){ 188 break; 189 } 190 ve[B[co].x].push_back(make_pair(B[co].y,B[co].v)); 191 ve[B[co].y].push_back(make_pair(B[co].x,B[co].v)); 192 co++; 193 } 194 Dijstra(); 195 isap_init(); 196 if(dis[n]==INF||n==1){ 197 cout<<0<<endl; 198 continue; 199 } 200 for(int i=0;i<co;i++){///判断是不是最短路上的边 201 if(dis[B[i].x]-dis[B[i].y]==B[i].v){ 202 add(B[i].y,B[i].x,1); 203 } 204 else if(dis[B[i].y]-dis[B[i].x]==B[i].v){ 205 add(B[i].x,B[i].y,1); 206 } 207 } 208 int s=1,t=n; 209 int ans=isap(s,t); 210 cout<<ans<<endl; 211 } 212 213 }
标签:sam include gap tom save from ott amp href
原文地址:https://www.cnblogs.com/Fighting-sh/p/9901752.html