2-SAT 问题是k-SAT问题在k==2时的特殊情况,因为已经证明k>=3时的k-sat问题属于npc问题。所以在这里仅研究2-SAT的特殊情况。

 
何为2-sat问题?
简单地说就是有N个集合,每个集合中有两个元素,其中一些集合中的元素存在相对关系。求出从每个集合中取出1个元素的方案。
 
先看一道例题:
2-sat的最简单情况,选出一些元素时,一些元素不可选。做这些题时,一般会考虑建图或者用并查集之类的数据结构维护。但显然复杂度是无法接受的,考虑新的算法。
 
首先,如果A1,A2,B1,B2分别为两个集合的两个元素。
且存在以下的排斥关系。
A1<->B2
B1<->A2
 
那么考虑从A1向B1连边,这条边意味着选了A1就必须选B1,因为显然选B2是不合法的。考虑相反情况。如果选了B2,就必须选A2,因为B2不可以和A1共存。 B1<->A2也是这样处理。
这时候我们就得到了一个图。把图中的一个强连通分量取出考虑,这个强连通分量里的每个元素都可以代表这一整个强连通分量,即选了这个强连通分量中的一个元素就必须选这个强连通分量里的所有元素,强连通分量里的元素部分取出构成的方案是不合法的(自己思考为什么)。同时,如果一个集合中的两个元素都位于一个强连通分量中也是不合法的。这时候各个元素中的相对关系就很显然了,采用topsort做最后的处理。
//COGS 313
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
#define FILE "spo"
;
const int oo=0x3f3f3f3f;
inline int read(){
      ,f=;
      ;ch=getchar();}
      +ch-';ch=getchar();}
      return x*f;
}
,group[MAXN],dfn[MAXN],low[MAXN],dfs_clock=,stack[MAXN],top=,group_num=,du[MAXN],opp[MAXN],LEN=,Link[MAXN],q[MAXN],head,tail,lable[MAXN];
bool vis[MAXN];
],E[MAXN<<];
namespace solution{
      inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
      inline void Insert(int x,int y){E[++LEN].next=Link[x];Link[x]=LEN;E[LEN].y=y;E[LEN].x=x;}
      void init(){
            N=read();M=read();N<<=;
            up(i,,M){
                  ,y=read()-;
                  insert(x,y^);
                  insert(y,x^);
            }
      }
      void tarjan(int node){
            dfn[node]=low[node]=++dfs_clock;
            stack[++top]=node;vis[node]=;
            for(int i=LINK[node];i;i=e[i].next)
                  if(!dfn[e[i].y]){
                        tarjan(e[i].y);
                        low[node]=min(low[node],low[e[i].y]);
                  }
                  else if(vis[e[i].y])low[node]=min(low[node],dfn[e[i].y]);
            if(low[node]==dfn[node]){
                  int tmp;
                  group_num++;
                  do{
                        tmp=stack[top--];
                        vis[tmp]=;
                        group[tmp]=group_num;
                  }while(tmp!=node);
            }
      }
      void slove(){
            memset(dfn,,sizeof(dfn));
            memset(low,,sizeof(low));
            memset(group,-,sizeof(group));
            memset(du,,sizeof(du));
            memset(lable,,sizeof(lable));
            up(i,,N-)if(!dfn[i])tarjan(i);
            up(i,,N-){
                  ]){
                        puts("NIE");
                        exit();
                  }
                  opp[group[i]]=group[i^];
                  opp[group[i^]]=group[i];
            }
            up(i,,len){
                  int x=e[i].x,y=e[i].y;
                  if(group[x]!=group[y]){
                        Insert(group[y],group[x]);
                        du[group[x]]++;
                  }
            }
            head=;tail=;
            up(i,,group_num))q[++tail]=i;
            for(;head<=tail;head++){
                  int node=q[head];
                  )continue;
                  lable[node]=;lable[opp[node]]=;
                  for(int i=Link[node];i;i=E[i].next)
                        )
                              q[++tail]=E[i].y;
            }
      }
      void output(){
            up(i,,N-))printf();
      }
}
int main(){
      //freopen("input.in","r",stdin);
      freopen(FILE".in","r",stdin);
      freopen(FILE".out","w",stdout);
      using namespace solution;
      init();
      slove();
      output();
      ;
}

POJ3207

这也是一道很简单的2-SAT题目,相比网络流2-SAT的题目更好看出模型..
这个相比上一题也更加简单,仅判断是否存在方案即可。
如果两个线段是相交的,那么两个线段同时在圆内或者圆外都是相交的。
这样就得到了约束关系,套用2-SAT的模板就行了。
 
//POJ 3207
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <algorithm>
#include <iomanip>
#include <string>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
      ,f=;
      ;ch=getchar();}
      +ch-';ch=getchar();}
      return x*f;
}
,st[MAXN],nd[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],dfs_clock=,top=,group[MAXN],group_num=;
bool vis[MAXN];
];
namespace solution{
      inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
      void init(){
            N=read();M=read();
            up(i,,M-){
                  int x=read(),y=read();
                  st[i]=min(x,y);nd[i]=max(x,y);
            }
      }
      void build(){
            up(i,,M-)up(j,i+,M-){
                  if((st[i]>st[j]&&st[i]<nd[j]&&nd[i]>nd[j])||(st[j]>st[i]&&st[j]<nd[i]&&nd[j]>nd[i])){
                        insert(i,j+M);
                        insert(j+M,i);
                        insert(j,i+M);
                        insert(i+M,j);
                  }
            }
      }
      void tarjan(int node){
            low[node]=dfn[node]=++dfs_clock;
            vis[node]=;stack[++top]=node;
            for(int i=LINK[node];i;i=e[i].next)
                  if(!dfn[e[i].y]){
                        tarjan(e[i].y);
                        low[node]=min(low[node],low[e[i].y]);
                  }
                  else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
            if(low[node]==dfn[node]){
                  int tmp;group_num++;
                  do{
                        tmp=stack[top--];
                        vis[tmp]=;
                        group[tmp]=group_num;
                  }while(tmp!=node);
            }
      }
      bool check(){
            up(i,,M);
            ;
      }
      void slove(){
            build();
            memset(dfn,,sizeof(dfn));
            memset(low,,sizeof(low));
            memset(vis,,sizeof(vis));
            up(i,,M<<)if(!dfn[i])tarjan(i);
            if(check())puts("panda is telling the truth...");
            else       puts("the evil panda is lying again");
      }
}
int main(){
      //freopen("input.in","r",stdin);
      using namespace solution;
      init();
      slove();
      ;
}

POJ 3683

这道题调了两个多小时....
要注意几点,一是标记的下放,二是邻接表存储时不要打混...邻接表的命名打混这个真心是挺难查的...
题目本身不算难,2-SAT的裸题,拆点建图即可。
还有就是如果对于当前的约束条件,只要这个约束条件是存在的,不管哪个以为着必须的边是否正确,都要连边。
同时要注意到标记的下放。dfs即可。
 
//POJ 3683
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
#include <algorithm>
#include <ctime>
#include <map>
#include <iomanip>
#include <cstring>
#include <string>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
      ,f=;
      ;ch=getchar();}
      +ch-';ch=getchar();}
      return x*f;
}
,dfn[MAXN],low[MAXN],dfs_clock=,stack[MAXN],top=,group[MAXN],group_num=,opp[MAXN],Link[MAXN],LEN=,du[MAXN],q[MAXN<<],head=,tail=;
int lable[MAXN];
bool vis[MAXN];
struct edge{int x,y,next;}e[MAXN*MAXN],E[MAXN*MAXN];
namespace solution{
      inline bool check(int st1,int nd1,int st2,int nd2){return (nd1<=st2)||(nd2<=st1);}
      inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
      inline void Insert(int x,int y){E[++LEN].next=Link[x];Link[x]=LEN;E[LEN].y=y;E[LEN].x=x;}
      inline void print(int a,int b){
            )printf("0%d:",a);
            else     printf("%d:",a);
            )printf("0%d",b);
            else     printf("%d",b);
            printf(" ");
      }
      void init(){
            N=read();
            up(i,,N){
                  int h1,m1,t1,h2,m2,t2,d;
                  scanf("%d:%d",&h1,&m1);
                  t1=h1*+m1;
                  scanf("%d:%d",&h2,&m2);
                  t2=h2*+m2;
                  st[i]=t1;nd[i]=t2;c[i]=read();
            }
      }
      void build(){
            up(i,,N)up(j,i+,N){
                  if(!check(st[i],st[i]+c[i],st[j],st[j]+c[j])){
                        insert(i,j+N);
                        insert(j,i+N);
                  }
                  if(!check(st[i],st[i]+c[i],nd[j]-c[j],nd[j])){
                        insert(i,j);
                        insert(j+N,i+N);
                  }
                  if(!check(nd[i]-c[i],nd[i],st[j],st[j]+c[j])){
                        insert(i+N,j+N);
                        insert(j,i);
                  }
                  if(!check(nd[i]-c[i],nd[i],nd[j]-c[j],nd[j])){
                        insert(i+N,j);
                        insert(j+N,i);
                  }
            }
      }
      void tarjan(int node){
            dfn[node]=low[node]=++dfs_clock;
            vis[node]=;stack[++top]=node;
            for(int i=LINK[node];i;i=e[i].next)
                  if(!dfn[e[i].y]){
                        tarjan(e[i].y);
                        low[node]=min(low[node],low[e[i].y]);
                  }
                  else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
            if(low[node]==dfn[node]){
                  int tmp;group_num++;
                  do{
                        tmp=stack[top--];
                        vis[tmp]=;
                        group[tmp]=group_num;
                  }while(tmp!=node);
            }
      }
      void re_build(){
            up(i,,N){
                  if(group[i]==group[i+N]){
                        puts("NO");
                        exit();
                  }
                  opp[group[i]]=group[i+N];
                  opp[group[i+N]]=group[i];
            }
            puts("YES");
            up(i,,len){
                  int x=e[i].x,y=e[i].y;
                  if(group[x]==group[y])continue;
                  Insert(group[y],group[x]);
                  du[group[x]]++;
            }
      }
      void downit(int node){
            if(lable[node])return;
            lable[node]=-;
            for(int i=Link[node];i;i=E[i].next)
                  downit(E[i].y);
      }
      void top_sort(){
            head=;tail=;
            up(i,,group_num))q[++tail]=i;
            for(;head<=tail;head++){
                  int node=q[head];
                  if(lable[node])continue;
                  lable[node]=;downit(opp[node]);
                  for(int i=Link[node];i;i=E[i].next)
                        )
                              q[++tail]=E[i].y;
            }
      }
      void slove(){
            memset(vis,,sizeof(vis));
            memset(dfn,,sizeof(dfn));
            memset(low,,sizeof(low));
            memset(du,,sizeof(du));
            memset(lable,,sizeof(lable));
            build();
            up(i,,N<<)if(!dfn[i])tarjan(i);
            re_build();
            top_sort();
      }
      void output(){
            up(i,,N){
                  ){print(st[i]/,st[i]%);printf(,(st[i]+c[i])%);}
                  ,(nd[i]-c[i])%);printf(,nd[i]%);}
                  printf("\n");
            }
      }
}
int main(){
      freopen("input.in","r",stdin);
      using namespace solution;
      init();
      slove();
      output();
      ;
}
 题目大意是给N个点M条边,每个点可以是0或者1,每条边是一个操作,每个一边的操作对应一个值,问是否有可行的方案
2-SAT的模型通常都很好观察出来。
 
这里的建模需要注意两个点。
1.op==and而且res==1。
这时候A点必须是1,B点也必须是1,如何保证这一点?

if(op==1&&res==1){
  insert(x,x+N);
  insert(y,y+N);
}

2.op==XOR是不需要连边的。

 我没搞懂为什么..但是好像是最后tarjan会自动的把那个xor的情况给处理掉。
//POJ 3678
//by Cydiater
//2016.8.3
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
      ,f=;
      ;ch=getchar();}
      +ch-';ch=getchar();}
      return x*f;
}
,dfn[MAXN],low[MAXN],stack[MAXN],top=,dfs_clock=,group_num=,group[MAXN];
bool vis[MAXN];
string s;
map<string,int>m;
struct edge{
      int x,y,next;
}e[MAXN<<];
namespace solution{
      inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
      void init(){
            m[;m[;m[;
            N=read();M=read();
            up(i,,M){
                  int x=read(),y=read(),res=read();cin>>s;
                  int op=m[s];
                  &&res==){
                        insert(x,x+N);
                        insert(y,y+N);
                  }
                  &&res==){
                        insert(x+N,y);
                        insert(y+N,x);
                  }
                  &&res==){
                        insert(x,y+N);
                        insert(y,x+N);
                  }
                  &&res==){
                        insert(x+N,x);
                        insert(y+N,y);
                  }
                  &&res==){
                        insert(x,y+N);
                        insert(y,x+N);
                        insert(y+N,x);
                        insert(x+N,y);
                  }
                  &&res==){
                        insert(x,y);
                        insert(y,x);
                        insert(x+N,y+N);
                        insert(y+N,x+N);
                  }
            }
      }
      void tarjan(int node){
            dfn[node]=low[node]=++dfs_clock;
            stack[++top]=node;vis[node]=;
            for(int i=LINK[node];i;i=e[i].next)
                  if(!dfn[e[i].y]){
                        tarjan(e[i].y);
                        low[node]=min(low[node],low[e[i].y]);
                  }else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
            if(low[node]==dfn[node]){
                  group_num++;
                  int tmp;
                  do{
                        tmp=stack[top--];
                        vis[tmp]=;
                        group[tmp]=group_num;
                  }while(tmp!=node);
            }
      }
      bool check(){
            up(i,,N-);
            ;
      }
      void slove(){
            memset(dfn,,sizeof(dfn));
            memset(low,,sizeof(low));
            memset(vis,,sizeof(vis));
            up(i,,N<<)if(!dfn[i])tarjan(i);
            if(check())puts("YES");
            else       puts("NO");
      }
}
int main(){
      //freopen("input.in","r",stdin);
      using namespace solution;
      init();
      slove();
      ;
}
最后一道2-SAT题目!
首先一些hate和friend的约束条件建图,然后根据二分出来的最长距离,对于i,j之间所有可能的路径:
i-S1-j
i-S2-j
i-S1-S2-j
i-S2-S1-j
如果存在大于lim的,也加入到约束条件中,判一下就行了。
 
//POJ 2749
//by Cydiater
//2016.8.8
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <iomanip>
#include <ctime>
#include <cmath>
#include <cstdlib>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
typedef pair<int,int> pii;
;
const int oo=0x3f3f3f3f;
inline int read(){
      ,f=;
      ;ch=getchar();}
      +ch-';ch=getchar();}
      return x*f;
}
pii S1,S2,node[MAXN],hate[MAXN],fri[MAXN];
int N,A,B,leftt,rightt,mid,LINK[MAXN],len,dfn[MAXN],low[MAXN],stack[MAXN],top,dfs_clock,group[MAXN],group_num;
bool vis[MAXN];
];
namespace solution{
      inline int dist(pii a,pii b){return abs(a.first-b.first)+abs(a.second-b.second);}
      inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
      void init(){
            N=read();A=read();B=read();
            int x=read(),y=read();
            S1=make_pair(x,y);
            x=read();y=read();
            S2=make_pair(x,y);
            up(i,,N){
                  int x=read(),y=read();
                  node[i]=make_pair(x,y);
            }
            up(i,,A){
                  int x=read(),y=read();
                  hate[i]=make_pair(x,y);
            }
            up(i,,B){
                  int x=read(),y=read();
                  fri[i]=make_pair(x,y);
            }
      }
      void tarjan(int node){
            stack[++top]=node;vis[node]=;
            low[node]=dfn[node]=++dfs_clock;
            for(int i=LINK[node];i;i=e[i].next)
                  if(!dfn[e[i].y]){
                        tarjan(e[i].y);
                        low[node]=min(low[node],low[e[i].y]);
                  }else if(vis[e[i].y])   low[node]=min(low[node],dfn[e[i].y]);
            if(dfn[node]==low[node]){
                  group_num++;int tmp;
                  do{
                        tmp=stack[top--];
                        vis[tmp]=;
                        group[tmp]=group_num;
                  }while(tmp!=node);
            }
      }
      bool check(int lim){
            len=;top=;dfs_clock=;group_num=;
            memset(LINK,,sizeof(LINK));
            memset(dfn,,sizeof(dfn));
            memset(low,,sizeof(low));
            memset(vis,,sizeof(vis));
            up(i,,A){
                  int x=hate[i].first,y=hate[i].second;
                  insert(x,y+N);
                  insert(y,x+N);
                  insert(x+N,y);
                  insert(y+N,x);
            }
            up(i,,B){
                  int x=fri[i].first,y=fri[i].second;
                  insert(x,y);
                  insert(y,x);
                  insert(x+N,y+N);
                  insert(y+N,x+N);
            }
            up(i,,N)up(j,i+,N){
                  if(dist(node[i],S1)+dist(S1,node[j])>lim){
                        insert(i,j+N);
                        insert(j,i+N);
                  }
                  if(dist(node[i],S2)+dist(S2,node[j])>lim){
                        insert(i+N,j);
                        insert(j+N,i);
                  }
                  if(dist(node[i],S1)+dist(S1,S2)+dist(S2,node[j])>lim){
                        insert(i,j);
                        insert(j+N,i+N);
                  }
                  if(dist(node[i],S2)+dist(S1,S2)+dist(S1,node[j])>lim){
                        insert(i+N,j+N);
                        insert(j,i);
                  }
            }
            up(i,,N<<)if(!dfn[i])tarjan(i);
            up(i,,N);
            ;
      }
      void slove(){
            leftt=;rightt=;
            <rightt){
                  mid=(leftt+rightt)>>;
                  if(check(mid))    rightt=mid;
                  else              leftt=mid;
            }
            if((!check(leftt))&&(!check(rightt)))puts("-1");
            else if(check(leftt))  printf("%d\n",leftt);
            else              printf("%d\n",rightt);
      }
}
int main(){
      //freopen("input.in","r",stdin);
      using namespace solution;
      init();
      slove();
      ;
}

2-SAT 问题的更多相关文章

  1. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

  2. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  3. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  4. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

  5. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  6. HIT 1917 2—SAT

    题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委 ...

  7. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  8. SAT考试里最难的数学题? · 三只猫的温暖

    问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我 ...

  9. 世界碰撞算法原理和总结(sat gjk)

    序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...

  10. hdu 4115 (2—SAT)

    题意:两个人石头剪刀布,一个人的出法已确定,另一个人的出法有一定约束,某两次要相同或者不同,问你第二个人能否全部都不失败. 思路:根据Bob出的情况,我们可以确定每次Alice有两种方案. R与P,S ...

随机推荐

  1. 基于PHP的AJAX学习笔记(教程)

    本文转载自:http://www.softeng.cn/?p=107 这是本人在学习ajax过程所做的笔记,通过本笔记的学习,可以完成ajax的快速入门.本笔记前端分别使用原生态的javascript ...

  2. 无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支

    无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支.发布此分支将导致远程存储库中的分支发生非快进更新. 第一次用oschina的git设置完远程仓库后提交出现 ...

  3. Beyond Compare 3 设置自动换行

    设置自动换行方法: 在菜单栏里点击“工具”,然后在弹出列表里选择“文件格式”,在弹出框的左下角编辑文件格式默认值中,选择“文本格式”,对右侧的 ‘每行字符限制’进行修改保存即可,一般可设置80或90. ...

  4. 东大OJ-最大子序列问题的变形

    1302: 最大子序列 时间限制: 1 Sec  内存限制: 128 MB 提交: 224  解决: 54 [提交][状态][讨论版] 题目描述 给定一个N个整数组成的序列,整数有正有负,找出两段不重 ...

  5. WEB 文件上传

    关键:<input name="file" type="file"/> 然后,在外面<form>层中必须写上:enctype=" ...

  6. Linux版本‘’大‘’全|形而上学

    1.Oracle Linux(下载地址) 清单: (1)Oracle Linux Release 7 for x86_64 (64 Bit) 2.debian(下载地址) 清单: (1)debian- ...

  7. 探索 SharePoint 2013 Search功能

    转载: http://www.cnblogs.com/OceanEyes/p/SharePont-2013-Search-Develop.html SharePoint 2013的搜索功能很强大,特别 ...

  8. [转]fastjson

    原文地址:http://www.cnblogs.com/zhenmingliu/archive/2011/12/29/2305775.html FastJSON是一个很好的java开源json工具类库 ...

  9. iOS开发小技巧--获取自定义的BarButtonItem中的自定义View的方法(customView)

    如果BarButtonItem是通过[[UIBarButtonItem alloc] initWithCustomView:(nonnull UIView *)]方法设置的.某些情况下需要修改BarB ...

  10. git 保存用户名和密码

    打开TortoiseGit控制面板 点击 Edit global .gitconfig文件 添加 [credential] helper = store OK了 你再登录一次之后密码就被记住了